This question is old but I struggled for a long time trying to get an answer to this problem that would work for my needs and did not easily find it. I believe my following solution is much better than the currently accepted one, perhaps because angular has added functionality since this question was originally posed.
Short answer, using the Module.value method allows you to pass data into a controller constructor.
See my plunker here
I create a model object, then associate it with the module's controller, referencing it with the name 'model'
HTML / JS
<html>
<head>
<script>
var model = {"id": 1, "name":"foo"};
$(document).ready(function(){
var module = angular.module('myApp', []);
module.value('model', model);
module.controller('MyController', ['model', MyController]);
angular.bootstrap(document, ['myApp']);
});
function confirmModelEdited() {
alert("model name: " + model.name + "\nmodel id: " + model.id);
}
</script>
</head>
<body >
<div ng-controller="MyController as controller">
id: {{controller.model.id}} <br>
name: <input ng-model="controller.model.name"/>{{controller.model.name}}
<br><button ng-click="controller.incrementId()">increment ID</button>
<br><button onclick="confirmModelEdited()">confirm model was edited</button>
</div>
</body>
</html>
The constructor in my controller then accepts a parameter with that same identifier 'model' which it can then access.
Controller
function MyController (model) {
this.model = model;
}
MyController.prototype.incrementId = function() {
this.model.id = this.model.id + 1;
}
Notes:
I'm using manual initialization of bootstrapping, which allows me to initialize my model before sending it over to angular. This plays much more nicely with existing code, as you can wait to set up your relevant data and only compile the angular subset of your app on demand when you want to.
In the plunker I've added a button to alert the values of the model object that was initially defined in javascript and passed to angular, just to confirm that angular is truly referencing the model object, rather than copying it and working with a copy.
On this line:
module.controller('MyController', ['model', MyController]);
I'm passing the MyController object into the Module.controller function, rather than declaring as a function inline. I think this allows us to far more clearly define our controller object, but Angular documentation tends to do it inline so I thought it bears clarification.
I'm using the "controller as" syntax and assigning values to the "this" property of MyController, rather than using the "$scope" variable. I believe this would work fine using $scope just as well, the controller assignment would then look something like this:
module.controller('MyController', ['$scope', 'model', MyController]);
and the controller constructor would have a signature like this:
function MyController ($scope, model) {
If for whatever reason you wanted to, you could also attach this model as a value of a second module, which you then attach as a dependency to your primary module.
I believe his solution is much better than the currently accepted one because
- The model passed to the controller is actually a javascript object, not a string that gets evaluated. It is a true reference to the object and changes to it affect other references to this model object.
- Angular says that the accepted answer's use of ng-init is a misuse, which this solution doesn't do.
The way Angular seems to work in most all other examples I've seen has the controller defining the data of the model, which never made sense to me, there is no separation between the model and the controller, that doesn't really seem like MVC to me. This solution allows you to really have a completely separate model object which you pass into the controller. Also of note, if you use the ng-include directive you can put all your angular html in a separate file, fully separating your model view and controller into separate modular pieces.