AngularJS noob在这里,我通往Angular Enlightenment的路上:)
情况如下:
我在模块“app”中实现了服务“AudioPlayer”,并按如下方式注册:
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);
};
}
这是“接收器” Controller (主要用于用户界面/表示逻辑)
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();
};
}
在我的 View 中,我显示当前的曲目信息,如下所示:
<div ng-controller="PlayerCtrl">
<button ng-click="next()"></button>
// ...
<p id="info">{{current.title}} by {{current.author}}</p>
</div>
next()方法是在PlayerCtrl中定义的,它仅在AudioPlayer服务上调用相同的方法。
问题
当存在手动交互时(即,当我单击next()按钮时),此方法很好用-流程如下:
但是,当从“后台”的AudioService内部调用next()方法时(即,当轨道结束时),从1到5的所有步骤都会发生,但是 View 不会收到有关更改的通知在PlayerCtrl的“当前”对象中。
我可以清楚地看到在PlayerCtrl中分配的新的跟踪对象,但这就像 View 没有收到有关更改的通知一样。我是菜鸟,我不确定这是否有帮助,但是我尝试过在PlayerCtrl中添加$ watch表达式
$scope.$watch('current', function(newVal, oldVal) {
console.log('Current changed');
})
仅在“手动”交互时才打印出来...
再次,就像我说的,如果我在$ on侦听器中添加console.log(current),如下所示:
$scope.$on('trackLoaded', function(event, track) {
$scope.current = track;
console.log($scope.current);
});
始终可以正确打印。
我究竟做错了什么?
(ps:我正在将AudioJS用于HTML5音频播放器,但我认为这不应该归咎于此...)
最佳答案
当您发生点击事件时,$ scope会更新,如果没有该事件,则需要使用$ apply
$scope.$apply(function () {
$scope.current = track;
});