我正在创建两个Angular指令fooContainer
和foo
,其中fooContainer
将加载一个或多个foo
元素并将其呈现在其容器中。
现在我还想将一些JavaScript事件附加到foo
指令编译的fooContainer
指令link
函数中,因为容器应该负责某些事情,比如拖动编译了foo
元素。
由于$ compile在使用templateUrl
编译指令时是异步的,因此在调用$compile(html)(scope)
之后HTML不能直接使用,但是如果我使用超时大约一秒钟,HTML将被呈现在我可以与它互动。
这不是最佳选择。 $ compile是否公开了一个事件或承诺,我可以用来在呈现所有HTML时收到通知?
以下是描述我的问题的Plunker http://plnkr.co/edit/coYdRqCsysV4txSFZ6DI?p=preview
答案 0 :(得分:1)
按优先顺序排列的方法:
1)尽可能遵循simmi simmi的模式并使用角度(ng -...)方法。这是最可靠的。
1.5)更新:Liquinaut'属性指令'下面的方法似乎是有效的 - 我只在快速演示POC中使用它并且它工作正常。假设存在更复杂的使用情况,我宁愿选择下面的watch / jquery选项2。但请注意,$ last专门用于ng-repeat。如果您按照OP注入$ compile大块的非重复标记,那么您需要删除$ last check。并且要明确这要求您将后渲染属性添加到您正在等待渲染的元素,即(根据OP plunker)
var el = $compile('<foo><div class="hide" post-render>...
带指令:
.directive('postRender', function() {
return function(scope, element, attrs) {
//your code here
element.hide();
};
});
我已经分叉了原始的plunkr并概括了允许传递通用回调的方法:http://plnkr.co/edit/iUdbn6zAuiX7bPMwwB81?p=preview
注意:此方法仅适用于编译元素的基本活动。如果编译字符串具有角度变量插值,例如{{value}}并且您依赖于在它无法工作的回调中解决这些问题。它们目前尚未得到解决。如果使用显式链接函数重写postRender指令,也是如此。下面的选项2适用于这些情况,因为它将解决方案推至至少下一个摘要。
2)我发现即使在非常复杂的应用程序中,DOM也非常可靠(尽管应始终监控性能)。用此块替换el.find('.hide').hide();
行:
scope.$watch(
function() { return element.find('.hide').length > 0;},
function(newVal, oldVal) {
if (newVal) {
//DO STUFF
el.find('.hide').hide();
}
}
);
我不习惯在紧密的循环中使用它,但是在指令实例化中使用一次(假设你没有创建1000个!)这似乎是合理的 - 我用这种方法进行ng / ui-slider集成等
3)如果你正在构建更复杂的东西(以及可重用的组件),pixelbits也会采用良好的架构方法,但要注意如果你使用transclude(例如嵌套指令)创建的额外范围,它将是$$ nextSibling &#39;发出&#39;。请参阅:here
BTW:如果只想快速拖放,请参阅:http://codef0rmer.github.io/angular-dragdrop/#/
答案 1 :(得分:0)
该指令触发postRender
事件:
fooContainer.directive('postRender', function() {
return function(scope, element, attrs) {
if (scope.$last){
//your code here
}
};
});
希望有所帮助!
答案 2 :(得分:0)
http://plnkr.co/edit/f4924y6GW7rAMItqVR0L?p=preview
.directive('fooContainer', function($compile, $timeout) {
return {
link: function(scope, element, attributes) {
console.log('link called');
var el = $compile('<foo><div class="hide" >I should always be hidden.</div><div class="hideDelay" ng-show="visiblity">I should be hidden after 1 second.</div></foo>')(scope);
element.append(el);
scope.visiblity=false;
},
restrict: 'E',
template: '<div class="fooContainer"></div>'
}
});
为什么不尝试使用ng-show / ng-hide
答案 3 :(得分:0)
您可以安全地将事件附加到指令的link函数中的元素,但仅限于指令的子元素。指令的父级尚未链接。
因此,在fooContainer的链接函数中,您知道foo已经被编译和链接,并且附加事件是安全的。
如果fooContainer链接后需要通知foo,您可以使用某种形式的指令间通信。即$ scope。$ emit。如果要将事件附加到foo,还可以在fooContainer的链接函数中使用jquery选择器。
根据Angular文档:
templateUrl
Same as template but the template is loaded from the specified URL.
Because the template loading is asynchronous the compilation/linking
is suspended until the template is loaded
这意味着您的模板已在链接功能执行时加载。不需要承诺对象。