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()按钮时),此方法很好用-流程如下:
  • PlayerCtrl拦截点击并触发其自己的next()方法
  • 会触发AudioPlayer.next()方法
  • ,它在播放列表中寻找下一个曲目,并调用loadTrack()方法
  • loadTrack()$广播“trackLoaded”事件(随其发送轨道本身)
  • PlayerCtrl
  • PlayerCtrl侦听广播事件并将轨道分配给当前对象
  • View 正确更新,显示current.title和current.author信息

  • 但是,当从“后台”的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;
    });
    

    07-22 15:36