繁体   English   中英

与已编译的Angular指令HTML进行交互

[英]Interact with compiled Angular directives HTML

我正在创建两个Angular指令fooContainerfoo ,其中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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM