Recently I came across the following in one of our projects. In one of our MVC views they are passing model data to an Angular controller through ngInit directive.

In xxx.cshtml:

<div ng-controller="AssessmentController"
     ng-init="Init('@Model.Status','@Model.ARN','@Model.AssessmentID','@Model.AssessorID',@Model.Contents, @Model.Date_of_Assessment.ToJsonTicks(),'@Model.HouseReferenceID',@Newtonsoft.Json.JsonConvert.SerializeObject(Model.House))">

I pointed out that according to Angular documentation, ngInit directive is not to be used to to initialize controllers.

Instead what I suggested was to send the ID in ngInit directive:

<div ng-controller="AssessmentController"

Then after that use $http service to get the remainder of data from the Angular controller.

The developer is refusing my idea saying it's faster to just send all the data through ngInit directive instead of having to do another call to get the data inti the Angular controller.

What do you think about this scenario? The only point I have right now is that this code is ugly and it not according to standards. How would you convince a developer to follow the path I suggested? Or am I completely wrong here?

  • Id say try ng-init="mystuff=@Html.Raw(JsonConvert.Serialize(Model))" But then you'd suffer from a little verbosity of having to use mystuff.this, mystuff.that.
    – Felype
    Jun 9 '15 at 13:40

Short version: Why are you serving up Angular views dynamically?

The root of the problem

Looking at your example, it seems like you're using Razor views to inject the model's data into the view. This seems to be a fairly counterproductive way of getting data into Angular. The full route is something like:

MVC controller -> Razor View -> Angular controller -> Angular View

Through that, you're embedding your model through a variety of layers, converting it back and forth.

To understand why this is problematic, let's take a step back. Angular is typically employed as a single page application (SPA) framework, where you serve up the HTML template itself once-off (vanilla HTML with ng-* directives). At some later point, Angular can then use this template in conjunction with a model (a JavaScript object), to render the view, and keep it data bound to the model. These models are typically retrieved directly as JSON objects from the server.

So, I'd say that typical usage would involve very little server-side templating, and most of the data communication would occur via XHR / JSON requests to something like Web API. This way, conversion to JSON is a straightforward (automatic) conversion done by MVC (or whatever JSON library you choose), and you don't have to repeat yourself at each layer. Your model object is just served up as JSON, and Angular now has it.

Efficiency - if we accept this approach, then we have one request for initially loading the view template, and then one request for each time you'd like to load an object and render the template. As an added bonus, the subsequent calls would only be retrieving the data, and not data + view each time.


To summarise, I think the usage you're describing is already relatively non-standard. Of course, there's nothing stopping you from using Angular in that fashion, but it's counter productive, and it makes it hard to talk about which approach is better. I suspect you can simplify your solution greatly by fully embracing Angular's approach, rather than working against it.

  • Thanks. I'm thinking of suggesting a change to this approach. What I'm thinking is getting rid of the MCV views. Use a basic html page for the spa. Use ngroute to do the routing with iis redirect. I will let you guys know how it goes. Hopefully the change will get approved into the project.
    – Kumudu
    Oct 16 '14 at 0:49
  • I too came to this dilemma. I am using Laravel application which has localized texts for validation, errors etc. Developers are used to add their own texts on the PHP side. Now I want to make all these texts available from JS code in a SPA. I have choices: 1) create server controller action which responds with texts, and then load the texts separately through some Angular service; 3) use ng-init on my top-level Angular controller to load the texts at once, and store the texts in a service. Ng-init seems more efficient than additional XHR request and server controller action. Jul 30 '15 at 9:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.