AngularJS noobは、AngularEnlightenmentへの道のりです:)
状況は次のとおりです。
モジュール「アプリ」内にサービス「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);
};
}
これが「レシーバー」コントローラーです(主にUI /プレゼンテーションロジック用)
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();
};
}
私の見解では、現在のトラック情報を次のように表示します。
<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()$ broadcasts'trackLoaded'イベント(トラック自体を送信します)
- PlayerCtrlはブロードキャストイベントをリッスンし、トラックを現在のオブジェクトに割り当てます
- ビューが正しく更新され、current.titleとcurrent.authorの情報が表示されます
ただし、「バックグラウンド」でAudioService内からnext()メソッドが呼び出された場合(つまり、トラックが終了した場合)、1から5までのすべてのステップが実行されますが、ビューには変更が通知されません。 PlayerCtrlの「現在の」オブジェクト内。
PlayerCtrlで割り当てられている新しいトラックオブジェクトをはっきりと見ることができますが、ビューに変更が通知されないようです。私は初心者で、これが役立つかどうかはわかりませんが、私が試したのは、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私はHTML5オーディオプレーヤーにAudioJSを使用していますが、これがここでの責任ではないと思います...)