【问题标题】:updating a {{ variable }} in my directive template在我的指令模板中更新 {{ variable }}
【发布时间】:2015-07-31 23:13:48
【问题描述】:

我不认为我理解如何在我的指令模板中正确设置{{ variable }}。我可以设法更新它的唯一方法是致电$scope.$apply(),而我要做的就是更新视频播放器的当前时间文本。

你可以在这里使用$scope.$apply()http://jsfiddle.net/ntdyp4oe/找到我的小提琴

目前这是我的指令,我想知道是否可以更新 {{ currentTime }} 而不必使用 $scope.$apply()

angular.module('canvas-video',[]).directive('canvasVideo', function($compile)
{
  return {
    restrict: 'E',
    replace:true,
    template:['',
      '<div id="canvas-video">',
        '<canvas id="canvas" ng-click="togglePlayback()" width="{{ width }}" height="{{ height }}"></canvas>',
        '<video src="{{ src }}" id="player"></video>',
        '<div id="controls">',
          '<div class="transport"><input id="slider" type="range" min="0" max="100" value="0" step="1"></div>',
          '<span class="current-time">{{ currentTime }}</span> | <span class="total-time">{{ totalTime }}</span>',
        '</div>',
      '</div>'
    ].join(''),
    scope: {
      src: '=',
      width: '=',
      height: '=',
      autoplay: '=?'
    },
    compile: function(element, attributes)
    {
      return {
        pre: function(scope, element, attributes)
        {
          if (!attributes.autoplay) attributes.autoplay = true;
          scope.currentTime = '00:00:00';
          scope.totalTime   = '00:00:00';
        },
        post: function(scope, element, attributes)
        {

        }
      }
    },
    controller: function($scope, $element, $attrs)
    {
      var canvas      = angular.element('canvas')[0];
      var ctx         = canvas.getContext('2d');
      var player      = angular.element('video')[0];
      player.autoplay = ($attrs.autoplay == 'false') ? 0 : 1;

      $scope.togglePlayback = function()
      {
        (player.paused) ? player.play() : player.pause();
      };

      $scope.renderPlayer = function()
      {
        var $this = this;
        $attrs.width = player.videoWidth;
        $attrs.height = player.videoHeight;
        canvas.setAttribute('width', $attrs.width);
        canvas.setAttribute('height', $attrs.height);
        $scope.totalTime = $scope.timecode(player.duration);

        (function loop()
        {
          if (!$this.paused && !$this.ended)
          {
            ctx.drawImage($this, 0,0, $attrs.width, $attrs.height);
            window.requestAnimationFrame(loop);
          }
        })();
      };

      //-- here is the function calling $apply a bunch and
      //-- wont update without it
      $scope.renderTime = function()
      {
        $scope.$apply(function()
        {
          $scope.currentTime = $scope.timecode(player.currentTime);
        });
      };

      $scope.timecode = function(seconds)
      {
        var minutes          = Math.floor(seconds/60);
        var remainingSec     = seconds % 60;
        var remainingMinutes = minutes % 60;
        var hours            = Math.floor(minutes/60);
        var floatSeconds     = Math.floor((remainingSec - Math.floor(remainingSec)) * 100);
        remainingSec         = Math.floor(remainingSec);
        return $scope.getTwoDigits(hours) + ":" + $scope.getTwoDigits(remainingMinutes) + ":" + $scope.getTwoDigits(remainingSec);
      };

      $scope.getTwoDigits = function(number)
      {
        return (number < 10) ? "0" + number : number;
      };

      player.addEventListener('timeupdate', $scope.renderTime);
      player.addEventListener('play', $scope.renderPlayer);
    }
  }
});

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    您确实需要将$apply() 用于更改 Angular 核心之外的范围的事件,以便让 Angular 知道运行视图摘要

    对于由 ng-click 等核心指令管理的事件,在内部调用 $apply()

    您的 DOM 侦听器不在这样的指令中。您还可以使用$timeout 来避免与digest in progress 发生错误冲突。

    如果摘要正在进行中,$timeout 将在内部推迟调用 $apply 本身

    【讨论】:

    • $timeout 会比调用$apply 更有效率吗?
    • 可能...因为您会经常调用它并且可能会或可能不会遇到冲突。或者也可以考虑直接更新元素文本
    • 啊,而不是绑定..是的,我认为直接更改文本可能是我最好的选择。
    猜你喜欢
    • 2013-12-28
    • 2014-07-02
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多