View不会从Service更新

时间:2015-09-06 20:55:17

标签: angularjs

我正在尝试从我的服务中显示一个对象(songTitle)。显示初始状态(tmp)。如果我要更改服务中的对象,则视图不会更新。

JS:

var party = angular.module("party", []);

party.run(function () {
      var tag = document.createElement('script');
      tag.src = "http://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});

party.service('PlayerService', function ($window) {
      this.playlist = [
            "https://www.youtube.com/watch?v=fnW2uLwHAas",
            "https://www.youtube.com/watch?v=iPT8DA32U6U",
            "https://www.youtube.com/watch?v=eGjEnfQl37s",
            "https://www.youtube.com/watch?v=nFtTY2S20mI",
            "https://www.youtube.com/watch?v=UmXQiPLoLTk",
            "https://www.youtube.com/watch?v=PbVx85DS9zc",
            "https://www.youtube.com/watch?v=ciidn3nEoiE",
            "https://www.youtube.com/watch?v=sm0DgkBEnUI",
            "https://www.youtube.com/watch?v=J2OCSWF7sAw",
            "https://www.youtube.com/watch?v=y_-giRHtuv8",
            "https://www.youtube.com/watch?v=iPT8DA32U6U",
            "https://www.youtube.com/watch?v=eGjEnfQl37s",
            "https://www.youtube.com/watch?v=nFtTY2S20mI",
            "https://www.youtube.com/watch?v=UmXQiPLoLTk",
            "https://www.youtube.com/watch?v=PbVx85DS9zc"
      ];
      this.player = {};
      this.pbTimer = null;
      this.songTitle = "tmp";

      $window.onYouTubeIframeAPIReady = function () {
            this.player = new YT.Player('ytplayer', {
                  height: '100',
                  width: '100',
                  videoId: 'ciidn3nEoiE',
                  events: {
                        'onReady': onPlayerReady
                  }
            });
      }


      function onPlayerReady() {
            console.log("db ready");
            songTitle = player.getVideoData().title;
            console.log(songTitle);
      }

      this.playVideo = function (url) {
            console.log("db playVideo " + url);
            player.loadVideoById(url.split("watch\?v=")[1], 0, "large");
            console.log(player);

      }

});
party.controller("FrontController", function ($scope) {
      $scope.front = {};
      $scope.front.title = "PARTY";
});

party.controller("PartyController", ['$scope', 'PlayerService', function ($scope, PlayerService) {
      $scope.party = {};
      $scope.party.title = "PARTY";
      Sortable.create(playlist, { /* options */ });
      $scope.playlist = PlayerService.playlist;
      $scope.playVideo = function (url) {
            PlayerService.playVideo(url);
      }
      $scope.songTitle = PlayerService.songTitle;
}]);

HTML

<body ng-app="party">
<div ng-controller="PartyController" class="container-fluid">
...
    <p id="playertitle">{{songTitle}}</p>
...

日志:

db ready 
Blackmill Feat. Veela - Life (Full Version)

1 个答案:

答案 0 :(得分:0)

问题出在您的onPlayerReady功能中。行songTitle = player.getVideoData().title;不会在您的服务上设置songTitle,而是在全局范围内设置window对象。仅使用this.songTitle也不会有任何帮助,因为thisonPlayerReady的范围内也没有引用您的服务。

最简单的解决方案是在onPlayerReady之外保存对您服务的引用,然后使用它来分配songTitle

var self = this;
function onPlayerReady() {
  console.log("db ready");
  self.songTitle = player.getVideoData().title;
  console.log(self.songTitle);
}

尽管如此,这还不够。因为您从Angular世界之外更改songTitle(Youtube播放器回调),您需要调用$scope.$apply来通知Angular某些内容已发生变化。

为此,您需要将$ rootScope注入您的服务:

party.service('PlayerService', function ($window, $rootScope)

并使用songTitle更改$rootScope.$apply

var self = this;
function onPlayerReady() {
  console.log("db ready");
  $rootScope.$apply(function() {
    self.songTitle = player.getVideoData().title;
    console.log(self.songTitle);
  });
}