Javascript 未在视图中更新表达式值
我正在使用angularjs编写一个chrome扩展。同样,我有一个控制器,如下所示:Javascript 未在视图中更新表达式值,javascript,angularjs,Javascript,Angularjs,我正在使用angularjs编写一个chrome扩展。同样,我有一个控制器,如下所示: app.controller('PageCtrl', ['$scope', function ($scope) { this.pageTitle = "xyz"; chrome.extension.sendMessage({ greeting: "PageDetails" }, function (pageDetailResponse) { consol
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);
}
});
}]);
上面的调用chrome.extension.sendMessage
异步调用作为参数传递的函数,我确信它被调用了,因为我可以看到我在函数中打印的两个日志。在html方面,我有以下内容:
<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>
-
-
-
{{page.pageTitle}}
{{page.pageUrl}
加载html时,我可以看到value
xyz
(我用它初始化的值)<代码>页面标题不反映回调函数中分配的新值。我是否在这里做了一个错误的假设,即如果我们更改控制器中的title变量,则更改不会反映在视图上?您需要通过在scope上运行$apply
方法手动运行摘要循环。当您在角度上下文之外修改范围时,也将varvm=this代码>函数外部,并使用vm
代替此选项,以确保您在函数内部共享相同的上下文
更好的方法是使用$timeout
应用
将运行摘要循环,但不会与当前运行的任何
消化
代码
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);
}
})
});
}]);
由于函数在angular的控制之外触发,因此必须手动应用更改
将函数包装如下:
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);
}
});
});
}]);
您需要应用摘要循环..当您在角度上下文之外修改范围时,还需要放置var vm=this代码>外部函数,并使用vm
而不是this
,这将确保您共享相同的上下文
这里需要检查的是,回调函数中的this
值是多少,是控制器吗。此外,我认为您必须将赋值包装到$scope中。$apply,因为回调似乎超出了角度上下文。Pankaj的解决方案也同样有效。将函数包装在apply中或在最后调用apply都可以。包装函数的优点是,如果你的handing函数有多个退出点,它仍然会被应用。我明白了!谢谢你的批改。。但是现在我得到了这个错误:[$rootScope:inprog]$apply已经在progress@labyrinth然后您需要使用$timeout
,这是应用摘要最安全的方法之一。。看看我在回答中的编辑,在我添加$timeout注入后,这个工作很好。另外,我不知道为什么,但将vm=this更改为vm=scope让我得到了结果。有什么不同吗?@迷宫是的..它们彼此都非常不同..使用此内部角度控制器将引导您使用controllerAs
语法和$scope
变量可在您的视图中直接访问..请您投票并接受答案..谢谢:)