我不认为我理解如何正确地在我的指令模板中设置{{ 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);
}
}
});
答案 0 :(得分:3)
您需要将$apply()
用于更改角度核心范围之外的事件,以便让角度知道运行视图摘要
对于由ng-click
等核心指令管理的事件,内部调用$apply()
。
您的DOM侦听器不在此类指令范围内。您还可以使用$timeout
来避免因发生digest in progress
错误而发生冲突。
$timeout
将在内部推迟调用$apply