Reputation: 1164
I am writing a chrome extension using angularjs. For the same I have a controller as follows:
app.controller('PageCtrl', ['$scope', function ($scope) {
this.pageTitle = "xyz";
chrome.extension.sendMessage({ greeting: "PageDetails" },
function (pageDetailResponse) {
console.log(pageDetailResponse);
if (pageDetailResponse.status) {
this.pageTitle = pageDetailResponse.title;
this.pageUrl = pageDetailResponse.url;
this.pageFaviconUrl = pageDetailResponse.favIconUrl;
status = true;
console.log("Updated var pagetitle to "+this.pageTitle);
}
});
}]);
The call chrome.extension.sendMessage
in the above calls the function passed as argument asynchronously and I am sure it is called since I can see both the logs that I have printed in the function. On the html side, I have the following:
<body ng-controller="PageCtrl as page">
<div ng-controller="TabsCtrl">
<section>
<ul>
<li ng-class="{active:isActiveTab(tab.url)}">
<a href="" ng-click="tab=1">Save Page</a>
</li>
<li ng-class="{active:isActiveTab(tab.url)}">
<a href="" ng-click="tab=2">Snapshot</a>
</li>
<li ng-class="{active:isActiveTab(tab.url)}">
<a href="" ng-click="tab=3">Annotate</a>
</li>
</ul>
</section>
<div class="popup-body" ng-show="tab === 1">
<h1>{{page.pageTitle}}</h1>
<textarea></textarea>
<div>
<img ng-src="{{page.pageFaviconUrl}}" />
<p>{{page.pageUrl}}</p>
</div>
</div>
</div>
</body>
When the html is loaded, I can see value xyz
(the value I have initialized it with). pagetitle
does not reflect the new value assigned in the callback function. Am I making a wrong assumption here that if we change the title variable in the controller, the change is not reflected on the view?
Upvotes: 1
Views: 60
Reputation: 136184
You need to run digest digest cycle manually by running $apply
method on scope. As you are modifying scope outside angular context and also place var vm=this;
outside function and use vm
instead of this that will assure you are sharing same context inside the function
.
More better way would be use
$timeout
to apply digest cycle that will run digest cycle but will not conflict with any currently running digest
Code
app.controller('PageCtrl', ['$scope', '$timeout', function($scope, $timeout) {
var vm = this;
vm.pageTitle = "xyz";
chrome.extension.sendMessage({
greeting: "PageDetails"
},
function(pageDetailResponse) {
$timeout(function() {
console.log(pageDetailResponse);
if (pageDetailResponse.status) {
vm.pageTitle = pageDetailResponse.title;
vm.pageUrl = pageDetailResponse.url;
vm.pageFaviconUrl = pageDetailResponse.favIconUrl;
status = true;
console.log("Updated var pagetitle to " + vm.pageTitle);
}
})
});
}]);
Upvotes: 1
Reputation: 3548
Because the function gets triggered outside of angular's control, you will have to manually apply the changes.
Wrap your function like this:
chrome.extension.sendMessage({ greeting: "PageDetails" },
function (pageDetailResponse) {
$scope.$apply(function() {
console.log(pageDetailResponse);
if (pageDetailResponse.status) {
this.pageTitle = pageDetailResponse.title;
this.pageUrl = pageDetailResponse.url;
this.pageFaviconUrl = pageDetailResponse.favIconUrl;
status = true;
console.log("Updated var pagetitle to "+this.pageTitle);
}
});
});
}]);
Upvotes: 1