AngularJS:service $ broadcast和$ watch在接收控制器上没有触发 [英] AngularJS : service $broadcast and $watch not triggering on receiving controller
问题描述
AngularJS noob在我的Angular Enlightenment之路上:)
AngularJS noob here, on my path to the Angular Enlightenment :)
情况如下:
我已经在我的模块'app'中实现了一个服务'AudioPlayer'并且注册如下:
I have implemented a service 'AudioPlayer' inside my module 'app' and registered like so:
app.service('AudioPlayer', function($rootScope) {
// ...
this.next = function () {
// loads the next track in the playlist
this.loadTrack(playlist[++playIndex]);
};
this.loadTrack = function(track) {
// ... loads the track and plays it
// broadcast 'trackLoaded' event when done
$rootScope.$broadcast('trackLoaded', track);
};
}
这里是'接收器'控制器(主要用于UI /演示逻辑)
and here's the 'receiver' controller (mostly for UI / presentation logic)
app.controller('PlayerCtrl', function PlayerCtrl($scope, AudioPlayer) {
// AudioPlayer broadcasts the event when the track is loaded
$scope.$on('trackLoaded', function(event, track) {
// assign the loaded track as the 'current'
$scope.current = track;
});
$scope.next = function() {
AudioPlayer.next();
};
}
在我的视图中我会显示当前的曲目信息:
in my views I show the current track info like so:
<div ng-controller="PlayerCtrl">
<button ng-click="next()"></button>
// ...
<p id="info">{{current.title}} by {{current.author}}</p>
</div>
下一个()方法是在PlayerCtrl中定义的,它只是在AudioPlayer上调用相同的方法服务。
the next() method is defined in the PlayerCtrl, and it simply invokes the same method on the AudioPlayer service.
问题
当手动互动时,此功能正常(即当我点击下一个()按钮时) - 流程如下:
This works fine when there is a manual interaction (ie when I click on the next() button) - the flow is the following:
- PlayerCtrl拦截点击并激活下一个点击()方法
- 反过来触发AudioPlayer.next()方法
- ,它搜索播放列表中的下一首曲目并调用loadTrack()方法
- loadTrack()$广播'trackLoaded'事件(用它发送轨道本身)
- PlayerCtrl监听广播事件并分配跟踪当前对象
- 视图正确更新,显示current.title和current.author信息
- PlayerCtrl intercepts the click and fires its own next() method
- which in turn fires the AudioPlayer.next() method
- which seeks the next track in the playlist and calls the loadTrack() method
- loadTrack() $broadcasts the 'trackLoaded' event (sending out the track itself with it)
- the PlayerCtrl listens the broadcast event and assigns the track to the current object
- the view updates correctly, showing the current.title and current.author info
然而,当在后台的AudioService中调用next()方法时(即,当轨道结束时),从1到5的所有步骤都会发生,但是视图不会被告知PlayerCtrl的当前对象的变化。
However, when the next() method is called from within the AudioService in the 'background' (ie, when the track is over), all the steps from 1 to 5 do happen, but the view doesn't get notified of the change in the PlayerCtrl's 'current' object.
我可以清楚地看到在PlayerCtrl中分配的新轨道对象,但就好像视图没有得到更改通知。我是一个菜鸟,我不确定这是否有任何帮助,但我尝试过在PlayerCtrl中添加一个$ watch表达式
I can see clearly the new track object being assigned in the PlayerCtrl, but it's as if the view doesn't get notified of the change. I'm a noob, and I'm not sure if this is of any help, but what I've tried is adding a $watch expression in the PlayerCtrl
$scope.$watch('current', function(newVal, oldVal) {
console.log('Current changed');
})
仅在手动互动期间打印出来...
which gets printed out only during the 'manual' interactions...
再次,就像我说的,如果我在$ on侦听器中添加一个console.log(当前),如下所示:
Again, like I said, if I add a console.log(current) in the $on listener like so:
$scope.$on('trackLoaded', function(event, track) {
$scope.current = track;
console.log($scope.current);
});
此报告始终正确打印。
我做错了什么?
(ps我正在为HTML5音频播放器使用AudioJS,但我认为这不应该归咎于此... 。)
(ps I'm using AudioJS for the HTML5 audio player but I don't think this is the one to blame here...)
推荐答案
当你有一个点击事件时,$ scope会更新,如果没有你需要使用$ apply的事件
When you have a click event the $scope is updated, without the event you'll need to use $apply
$scope.$apply(function () {
$scope.current = track;
});
这篇关于AngularJS:service $ broadcast和$ watch在接收控制器上没有触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!