AngularJS - 在两个控制器之间共享变量

时间:2017-04-29 15:32:48

标签: angularjs

我有两个必须相互通信的控制器。 第一个引用视频播放器,第二个引用时间线。

从第一个开始,我得到视频播放的currentTime,我想将其传递给第二个应该在视频播放时移动时间栏的视频。

我尝试使用工厂在控制器之间共享一个名为time的变量,但这在此期间不会改变。

第一个控制器

angular.module('videoCtrl', ['vjs.video'])
  .controller('videoController', ['$scope', 'Timeline', function (scope, Timeline) {
        scope.mediaToggle = {
            sources: [
                {
                    src: 'http://static.videogular.com/assets/videos/videogular.mp4',
                    type: 'video/mp4'
                }
            ],
        };

        //listen for when the vjs-media object changes
        scope.$on('vjsVideoReady', function (e, videoData) {
          videoData.player.on('timeupdate', function () {
            var time = this.currentTime();
            Timeline.setTime(time); // setting the time on factory
          })
        });
    }]);

第二个控制器

angular.module('timelineCtrl', ['mt.media-timeline'])
    .controller('timelineController', function ($scope, Timeline) {
    $scope.time = Timeline.getTime(); // here I'm trying to get the time
  });

工厂

.factory('Timeline', function(){
    var timelines = [];
    var time = null;
    return {

      getTime: function() {
        return time;
      },

      setTime: function(_time) {
        time = _time;
      }

    }
  });

3 个答案:

答案 0 :(得分:5)

time似乎是原始的,这意味着它返回 byVal 而不是 byRef 。换句话说,每次调用getTime都会返回time当前设置的值,对setTime的调用将更改以后调用的值,但不会更改已调用的任何值它。这是角度规则的经典案例,始终使用点

尝试将time改为对象:

.factory('Timeline', function() {
  var timelines = [];
  var time = {
    value: null
  };
  return {

    getTime: function() {
      return time;
    },

    setTime: function(_time) {
      time.value = _time;
    }

  }
});

在您的HTML中,使用{{time.value}}

答案 1 :(得分:0)

保存在$rootScope而不是$scope可以让您在所有应用和控制器中访问变量。但请记住,创建大量$ rootScope可能会影响应用程序的性能。

不要忘记将$rootScope注入控制器(就像使用$ scope一样),以便您可以访问它。

答案 2 :(得分:0)

据我所知,在第二个控制器中正在做的是你在实例化控制器时检索时间值。当然,服务价值的进一步变化无法通过这种方式获得。要做到这一点,可以在第二个控制器中使用$scope.$watch

angular.module('timelineCtrl', ['mt.media-timeline'])
    .controller('timelineController', function ($scope, Timeline) {
    $scope.time = Timeline.getTime(); //Set the time once so it's not undefined

    $scope.$watch(
      function() {return Timeline.getTime();},
      function(newVal) {$scope.time = newVal;}
    );
});

Angular将在每个$digest周期调用第一个函数(如果我没记错的话,至少每10毫秒一次),并在检测到更改时调用第二个函数。可以找到$watch的详细文档here

这是一种方法。您还可以向$scope添加一个函数(例如getTime()),该函数应返回当前时间,然后在HTML模板中调用此函数:{{getTime()}}。两种方式几乎都以相同的方式工作,除了第二种方式将“脏”工作留给角度(创建观察者和更新值)