[英]Interact with compiled Angular directives HTML
我正在创建两个Angular指令fooContainer
和foo
,其中fooContainer
将加载一个或多个foo
元素并将其呈现在其容器中。
现在,我还想将一些JavaScript事件从fooContainer
指令link
功能附加到foo
指令编译的HTML的foo
指令,因为该容器应该负责诸如拖动已编译的foo
元素之类的某些事情。
由于在使用templateUrl
编译指令时$ compile是异步的,因此在调用$compile(html)(scope)
后无法直接使用$compile(html)(scope)
,但是,如果我使用超时约一秒钟,则会呈现HTML,并且可以与之交互。
这不是最佳选择。 $ compile是否公开一个事件或保证在渲染所有HTML时可以用来通知我?
这是一个描述我的问题的柱塞, http ://plnkr.co/edit/coYdRqCsysV4txSFZ6DI?p = preview
优先顺序的方法:
1)尽可能遵循simmi simmi模式,并使用角度(ng -...)方法。 这是最可靠的。
1.5)更新:以下Liquinaut的“属性指令”方法似乎有效-我仅在快速演示POC中使用了它,并且效果很好。 假设这种情况在更复杂的用法中仍然有效,那么我宁愿使用下面的watch / jquery选项2。 但是请注意,$ last是专门用于ng-repeat的。 如果您要按OP注入非重复标记的$ compile块,则需要删除$ last检查。 需要明确的是,这需要您将属性post-render添加到等待渲染的元素中,例如(每个OP插件)
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(例如嵌套指令),则会产生额外的作用域, ”。 看到: 这里
顺便说一句:如果只是想要一种快速的拖放方法,请参见: http : //codef0rmer.github.io/angular-dragdrop/#/
指令触发一个postRender
事件:
fooContainer.directive('postRender', function() {
return function(scope, element, attrs) {
if (scope.$last){
//your code here
}
};
});
希望有帮助!
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
您可以安全地将事件附加到指令的链接功能中的元素上,但仅适用于指令的子级。 该指令的父级尚未链接。
因此,在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
这意味着您的模板将在链接函数执行时加载。 不需要promise对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.