Angular controller scope not updating after jQuery ajax call
我有这个代码,我看不出问题的根源在哪里,在Chrome控制台中没有任何错误。我的控制器:
1 2 3 4 5 6 7 8 9 10 11
| function notifController($scope) {
$scope.refreshMsgs = function () {
$.post("notification-center-trait.aspx")
.success(function (data) {
$("#loadedthings").html(data);
newMsgs = JSON.parse($("#label1").html());
$scope.msgs = newMsgs;
});
}
$scope.refreshMsgs();
} |
label1和label2在DIV加载的铰链内正确加载;
控制台中的newmsgs按照它应该的方式进行解析;
我让它在其他页面上运行,但似乎我在这一页上遗漏了一些东西。我有标签:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| {{msgs.length}} new msgs :
<table class="table">
<tbody >
<tr ng-repeat="msg in msgs">
<td>
{{msg.sender}}
</td>
<td>
{{msg.message}}
</td>
<td>
{{msg.date}}
</td>
</tr>
</tbody>
</table> |
当我执行以下命令时,控制台中的"未定义":angular.element($0).scope()。
- 你确定$0在工作吗?我不知道你在做什么…
- 我测试了你的代码,这里的一切都正常工作。我怀疑你不恰当地处理了国内事务,犯了一个错误。任何类似于angular.element的东西都属于指令。Angular使Scope属性在任何需要的地方都可用,除了极少数的异常之外,因此不需要以这种方式访问元素或范围。
- @M59我刚刚在Chrome控制台中执行了angular.element($0).scope(),只是为了查看我的作用域链接中发生了什么,但是我得到了"未定义"。
- 如我所说,使用这里的代码,控制器被初始化,数据绑定工作正常。您遇到的问题未在此代码中传达。当然,可以这样做:$scope.foo = 'test'和在您的标记中:{{foo}}。也许你的Ajax电话打不通?如果控制器确实不工作,那么问题就出在其他方面(不在本代码中)。
- 顺便说一句,不管angular.element是什么,你都有一个控制器的全局函数(不好的做法),你在控制器中调用了ajax(应该在服务中),在控制器中使用.html()进行了dom操作(应该在指令中)。如果这只是一个测试,也没关系,但是您可能需要为生产代码研究这些东西。
- @M59当我把一个字符串放在像$scope.foo ="test" ;{{test}}这样的范围内时,我已经测试了很多东西,但是使用一个json对象:$scope.newMsgs = {'message':'hello'};{{newMsgs.message}}不起作用。
- 你刚才所描述的甚至都不正确…那必须是{{foo}}。我敢肯定,您肯定有一个可以用控制台调试的简单错误。另外,angular有用于Ajax调用的$http,您应该使用它而不是jquery。
- @M59是的,是的,我很抱歉foo正在工作抱歉,但json对象没有
- 终于!$http是解决方案,非常感谢@m59!!
不管我在评论中指出的其他建筑问题,真正的问题是你使用的是jQuery的ajax,而不是angular的$http。当你不通过角度来做类似的事情时,你在角度的范围之外工作,它不知道变化。虽然不理想,但您可以使用$scope.$apply让angular知道一些超出其知识范围的更新。就像这样:
1 2 3
| $scope.$apply(function() {
$scope.msgs = newMsgs;
}); |
这意味着Angular已经从它不知道的上下文(本例中的jQueryAjax调用)中修改了它需要知道的内容。
$scope.$apply()有一些有效的用途,例如在事件处理程序中,但在大多数情况下,它是坏做法的标志。对于Ajax调用,您肯定应该使用Angular的$http。
- 作为一个附录,$scope.$apply如果在错误的时间使用它(你不能把它放在你行为错误的任何地方,作为所有错误的解决方案),那么$timeout(settimeout的一个角度包装器)会一直表现出来,并确保你的更改最终会出现在下一个$apply通行证中(这是它们无论如何都会到达的地方)。)它不应该被滥用,但是它比$apply更安全,在指令中没有肮脏的黑客,检查它是否安全/需要。
- @Norguard是真的……但是如果你曾经在一个地方使用$apply,它会抛出一个错误,那么它根本就不应该被使用。这是一种巨大的代码味道。如我所说,除非您使用活动或第三方库,否则通常根本不需要$apply。
- 当然。但是,有些第三方库是半同步、半异步的,而另一些则是在自己的酒吧/酒吧或休息时间里钻空子,或者只是要求你自己在这些圈子里绕着它们跳舞。我知道第一手,如果你不小心的话,masonryjs(用于Pinterest/Infinite Tumble布局)和d3js(用于生成可吐温的svg图)都可以用if (!$scope.$rootScope.$$phase)的废话提供他们的痛苦,如果角只部分地与过程联系在一起(比如在ng repeat上调用msnry.stamp+msnry.layout…)。$timeout非常优雅。
- @诺加特啊,很好的补充!