我正在尝试将video.js
库连接到我的应用中。在应用程序的一部分,用户可以上传可能包含视频的文件,因此在输出时,我使用ng-repeat
循环播放视频,并输出HTML5
视频标记。我现在想要将一个指令附加到视频标记,以便video.js
可以与它一起使用。
我的视频输出定义为
<video ng-src="{{video.url}}" ng-repeat="video in post.attachments.video" type="{{video.mimetype}}" controls preload="metadata" id="video_{{video.id}}" video>
对于我的video
指令,我基本上只想运行videojs
函数来设置它,所以我想调用
videojs(attrs.id, {
controls: true,
preload: "metadata",
techOrder: ["flash"]
}, function() {});
这是被调用的,但我遇到的问题是ng-repeat
在调用此指令时尚未完成所有操作,因此attrs.id
仍然是video_{{video.id}}
而不是我想要的video_23
。
在我的视频指令运行之前,我怎么能等到ng-repeat
完成它的事情所以我知道我可以使用ID属性?
我目前正在使用Angular 1.1.4。
现在,我的指示已经
app.directive("video", function($parse) {
"use strict";
return {
restrict: "A",
link: function(scope, elm, attrs) {
videojs(attrs.id, {
controls: true,
preload: "metadata",
techOrder: ["flash"]
}, function() {});
}
};
});
答案 0 :(得分:1)
问题是在尝试访问插值时尚未执行字符串插值。您可以使用attrs.$observe(...)
来完成此操作。以下是AngularJS文档的link(或在下面阅读)。
...
link: function(scope, element, attrs) {
attrs.$observe('id', function() {
videojs(attrs.id, {
controls: true,
preload: "metadata",
techOrder: ["flash"]
}, function() {});
});
}
...
我还创建了一个显示此行为的plunker。
修改:更新了正确答案。
编辑2 :来自Angular文档:
使用
$observe
观察包含的属性的值更改 插值(例如src="{{bar}}"
)。这不仅非常有效 但它也是轻松获得实际价值的唯一方法,因为 在链接阶段,尚未评估插值 所以此时的值设置为undefined。
答案 1 :(得分:0)
您可以为指令指定priority
。来自文档AngularJS: Directives:
priority - 当在单个DOM元素上定义了多个指令时,有时需要指定应用指令的顺序。优先级用于在调用编译函数之前对指令进行排序。优先级定义为数字。首先编译具有更高数字优先级的指令。具有相同优先级的指令的顺序是未定义的。默认优先级为0。
编辑: 实际上,这看起来非常类似于这个问题:How to get evaluated attributes inside a custom directive
答案 2 :(得分:0)
最后有一个解决方案。这不是最好的(由于角度缺乏回调),但它正在发挥作用。我的最终指示是
app.directive("video", function($timeout) {
"use strict";
return {
restrict: "A",
compile: function(cElm, cAttrs) {
return function postLink(scope, elm, attrs) {
// We have to wait until it's actually rendered. Stupid angular with no callback!
$timeout(function() {
videojs(scope.$eval(attrs.video), {
controls: true,
preload: "metadata",
techOrder: ["flash"]
}, function() {});
})
}
}
};
});
我还必须将html的定义更改为
<video ng-src="{{video.url}}" ng-repeat="video in post.attachments.video" type="{{video.mimetype}}" controls preload="metadata" id="video_{{video.id}}" video="'video_' + video.id">
请注意在video
属性中添加了表达式,因为id
属性中使用的表达式无法在eval
中使用。
我还必须使用烦人的$timeout
hack,因为尝试初始化视频。对于元素ID的j.js没有工作,因为角度没有完成呈现元素,所以当video.js尝试要在DOM中找到具有该ID的元素,它与任何内容都不匹配。使用$timeout
修复此问题虽然我并不过分热衷于此。
如果有人对此有更好的解决方案,那么我全都耳朵:)