I have come across an issue and created a JSFiddle to demonstrate
var myApp = angular.module("myApp", []);
myApp.component("bar", {
transclude: true,
template: '<div ng-transclude></div>',
controller: function ($scope, $element, $attrs) {
$scope.msg = "Hello";
setTimeout(function(){
$scope.msg = "Goodbye";
alert($scope.msg);
}, 3000)
}
});
HTML:
<body ng-app="myApp">
<bar>
{{ $parent.msg }}
</bar>
</body>
As you can see I have a scope variable (msg) that I am updating after I do some work (setTimeout in this case). There seems to be only one-way binding in the HTML, because "Goodbye" is never rendered to the view when the component's scope is updated.
Am I correct to be using $parent
? Have I got my scope all wrong? Am I handling transclusion properly?
Edit
I should say that setTimeout
is only a example, in my real world case I am trying to add components for http://www.createjs.com/
Instead of setTimeout
I was actually adding a 'complete' event listener to a PreLoadJS LoadQueue
http://www.createjs.com/docs/preloadjs/classes/LoadQueue.html
the reason is you are doing this inside setTimeout
which is not in angular context. Any time you update scope outside of angular context you need to notify angular to run a digest to update view
Angular provides a service $timeout
that takes care of this for you.
Try:
controller: function ($scope, $element, $attrs, $timeout) {
$scope.msg = "Hello";
$timeout(function(){
$scope.msg = "Goodbye";
alert($scope.msg);
}, 3000)
}