I have read threads on this issue such as: The view is not updated in AngularJS but I still can't understand how to apply it on my simple example.
I have this function:
function MyPageView($scope) {
var myModel = new MyModel();
$scope.myModel = myModel;
}
when myModel
is updated elsewhere in the code (when user clicks, interacts, send XHR requests) it doesn't update my view. I understand I need to do something with $apply but I didn't understand where and how.
Can someone explain to me how do I solve this issue for this simple use-case?
My model looks something like this (if that is necessary for the question) - it has no AngularJS code inside of it:
var MyModel = function() {
var _this = this;
...
_this.load = function(){...};
_this.updateModel = function(){...};
...
return _this;
}
adding a JSfiddle example: http://jsfiddle.net/DAk8r/2/
In Angular apps, models are
normallysometimes implemented on $scope, not as a separate JavaScript object. Here is a rewrite of your app showing how to do thatHTML:
Here's a fiddle, with no jQuery, and it shows the "normal way" of setting up a fiddle for Angular.
try $scope.$apply() inside your controller after you update your model
The crux of your problem is that you're trying to mix AngularJS with a very traditional, "jQuery-soup style" JavaScript pattern. In Angular, you should always use directives to do DOM manipulation and interaction (including clicks). In this case, your code should look more like the following:
Notice how, instead of setting up a manual
click
handler with jQuery, we use Angular's built-inng-click
directive. This allows us to tie in to the Angular scope lifecycle, and correctly update the view when the user clicks the link.Here's a quote from the AngularJS FAQ; I've bolded a part that might help you break the habit.
Finally, here your example, working using this technique: http://jsfiddle.net/BinaryMuse/xFULR/1/
http://jsfiddle.net/zCC2c/
Your problem is twofold.
1) There was a syntax error in your jsfiddle, as DOMElements (such as the a returned by $(this) inside your clickhandler have no prevent default. You actually needed to pass an event. (Minor syntax issue).
2) By putting your variable definition within the controllers scope like so:
You ensure it gets run once per class instantiation.
What you want is:
And then on your link
For a more exhaustive codesample see the linked jsfiddle.
A good overview of the theory can be found in the first talk here:
http://www.youtube.com/watch?feature=player_embedded&v=VxuN6WO3tIA