Reputation: 683
is there a way to make the $broadcast propagate the variable to the $on during initialization phase?
<div ng-app='test'>
<div ng-controller='testCtrl'> <span>{{testContent}}</span>
</div>
<div ng-controller="testCtrl2">
<input type='text' ng-change="updateContent()" ng-model="testContent2" />
</div>
</div>
var app = angular.module('test', []);
app.factory('sharedContent', function ($rootScope) {
var standardContent;
var resizeProportion;
return {
setStandardContent: function (newStandardContent) {
standardContent = newStandardContent;
$rootScope.$broadcast('updateContent');
console.log('broadcast');
},
getStandardContent: function () {
return standardContent;
},
setResizeProportion: function (newResizeProportion) {
$rootScope.$broadcast('updateResizeProportion');
},
}
});
app.run(function (sharedContent) {
sharedContent.setStandardContent('haha');
});
function testCtrl($scope, sharedContent) {
$scope.testContent;
$scope.$on('updateContent', function () {
console.log('receive');
$scope.testContent = sharedContent.getStandardContent();
});
}
function testCtrl2($scope, sharedContent) {
$scope.testContent2 = 'test';
$scope.updateContent = function () {
sharedContent.setStandardContent($scope.testContent2);
};
}
Sample fiddle : http://jsfiddle.net/jiaming/NsVPe/
The span will display the value as the input changes, which is due to the ng-change function.
However, at initialization phase, the value "haha" was not propagated to the $scope.testContent and thus, nothing was shown at first runtime. Is there a way to make the value "haha" appear at the first runtime?
Thank you.
Upvotes: 8
Views: 10056
Reputation: 109
Just provide a little delay using $timeout
function. Just update the code in the factory it will start working.
Please refer the code below for the factory:
app.factory('sharedContent', function ($rootScope,$timeout) {
var standardContent;
var resizeProportion;
return {
setStandardContent: function (newStandardContent) {
standardContent = newStandardContent;
$timeout(function(){
$rootScope.$broadcast('updateContent');
},0)
console.log('broadcast');
},
getStandardContent: function () {
return standardContent;
},
setResizeProportion: function (newResizeProportion) {
$rootScope.$broadcast('updateResizeProportion');
},
}
});
Upvotes: 1
Reputation: 341
The thing that you are not taking into account that the run
phase of the app gets executed before the controllers are initialized. Because broadcasted messages don't get buffered and are only served to the listeners that are listening in the moment the message is created, the haha
value gets lost.
In your case, however, it's quite easy to make it work with a small change in your controller:
function testCtrl($scope, sharedContent) {
updateTestContent();
$scope.$on('updateContent', updateTestContent);
function updateTestContent(){
$scope.testContent = sharedContent.getStandardContent();
}
}
I forked your JSFiddle here http://jsfiddle.net/y3w5r01d/2/ where you can see on the console when each function (run and controllers) gets executed.
Upvotes: 0
Reputation: 11228
The reason for this is that the ng-change
triggers upon subsequent changes to the model identified by testContent2
. When the controller initializes, the value "test" is assigned to it. ng-change
then keeps a track of subsequent changes - the initial assignment does not qualify for this, only subsequent changes do.
http://jsfiddle.net/vZwy4/ - I updated the fiddle provided by you. Here you can see that the span
tag is correctly populated with the data.
What you needed to do was instead of using ng-change
, you should use the scope's $watch
functionality. So remove the ng-change
directive from the input box and remove the updateContent
method. Instead, replace it with the following code wherein you watch the changes to the testContent2
model:
$scope.$watch('testContent2', function () {
if ($scope.testContent2 === undefined || $scope.testContent2 === null) {
return;
}
sharedContent.setStandardContent($scope.testContent2);
});
You can now see that the word "test" (I could not find anything to do with 'haha') appears the moment the page loads. Subsequent changes to the input are also updated in the span
. Hope this is what you were looking for.
Upvotes: 0