AngularJS:service $ broadcast和$ watch在接收控制器上没有触发 [英] AngularJS : service $broadcast and $watch not triggering on receiving controller

查看:57
本文介绍了AngularJS:service $ broadcast和$ watch在接收控制器上没有触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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:


  1. PlayerCtrl拦截点击并激活下一个点击()方法

  2. 反过来触发AudioPlayer.next()方法

  3. ,它搜索播放列表中的下一首曲目并调用loadTrack()方法

  4. loadTrack()$广播'trackLoaded'事件(用它发送轨道本身)

  5. PlayerCtrl监听广播事件并分配跟踪当前对象

  6. 视图正确更新,显示current.title和current.author信息

  1. PlayerCtrl intercepts the click and fires its own next() method
  2. which in turn fires the AudioPlayer.next() method
  3. which seeks the next track in the playlist and calls the loadTrack() method
  4. loadTrack() $broadcasts the 'trackLoaded' event (sending out the track itself with it)
  5. the PlayerCtrl listens the broadcast event and assigns the track to the current object
  6. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆