在我的 Controller 构造函数中,我调用了以下函数:
constructor(private $scope, private $log : ng.ILogService, private lobbyStorage, private socketService) {
this.init();
}
private init(){
this.lobbyData = [];
this.initializeLobbyData();
// DOM related initialisation
this.chatWindow = $('.chat-output');
var self = this;
this.$scope.$watch(
function () {
return self.socketService.chatHistory
},
function (newValue, oldValue) {
if(typeof newValue.body !== "undefined" && newValue.body.data.length > 0){
// Delete existing records
self.chatWindow.empty();
for (var i = 0; i < newValue.body.data.length; ++i) {
console.log(newValue.body.data[i].body.userName)
self.chatWindow.append($('<span><strong>' + newValue.body.data[i].body.userName + '</strong> ' + newValue.body.data[i].body.message + '<br></span>'));
}
}
}
);
this.socketService.setUpWebsocketService();
}
这是假设从使用 websocket 的 AngularJS 服务中观察外部变量。
当我在浏览器 (Chrome) 中调试代码时,$watcher
的回调函数被调用两次并最终将数据加载到 chatWindow。
只要我在没有调试器的情况下运行网络应用程序,数据就不会加载。
我需要做的是点击页面上的按钮。出于某种原因,与页面的任何类型的交互(例如按钮、anker)似乎都会导致向聊天窗口显示数据。
当我在调试器窗口中时,不需要相同的交互。数据在我这边没有任何交互的情况下加载。
有人对此有解释吗?
最佳答案
这是因为$watch
仅在摘要周期中运行,即在 $scope.$apply()
之后被某人调用。当 ng-click
时,Angular 会为你做这件事发生了,但你的 websocket 库可能不会这样做,所以你必须调用 $scope.$apply()
每当结果通过 websocket 返回时手动。
另见 AngularJS' $scope
documentation .
无关:小心,你的$('<span>'... + someUserName)
line 可能是您服务中的 XSS 漏洞,允许用户注入(inject)例如他们的聊天消息中的标签。
关于javascript - AngularJS - 在外部 AngularJS 服务变量上使用 $watcher 时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32011816/