【问题标题】:AngularJS - How do I avoid using $timeout to wait for an element to be created?AngularJS - 如何避免使用 $timeout 来等待创建元素?
【发布时间】:2013-07-11 01:25:31
【问题描述】:

这是一个想法:

所以我尝试使用外部库函数在我的 ng-repeat 连接到的控制器之一中的 DOM 中创建一些操作。

最新的 jsFiddle 工作,但 ...

http://jsfiddle.net/GeorgiAngelov/KRbdL/150/

所以基本上我在 @BrandonTilley 的帮助下得到了它,但我试图避免使用 $timeout,因为我认为它不是一个可行的解决方案,而是一个 hack。

@BrandonTilley 帮助下的新小提琴

添加了 onload 监听器,我也试图通过 getElementById 获取新元素或其父元素,但它返回的都是 NULL。

http://jsfiddle.net/GeorgiAngelov/KRbdL/143/

问题如下: 我在我的控制器中调用那个将元素添加到 ng-repeat 数组的外部函数,它在术语中将新元素添加到 DOM。但是,当我在控制器内部时,该元素还不存在,即使我已将其添加到数组中。

如何绑定一个外部函数以在元素实际附加到 DOM 后调用,而不是在元素实际添加到控制 ng-repeat 的数组时调用?

问题来了,我有模板 1 调用模板 2,然后模板 2 调用模板 3,然后模板 3 回调模板 2,一旦模板 3 完成渲染模板 2,我想将模板 3 中的一个元素连接到模板 2。

我创建了一个链接到 template3 的指令,我使用了 $last 属性,但它仍然无法工作,因为 template3 加载但我不知道 template2 何时完成加载。此外,element.ready() 甚至没有触发向上。我还尝试使用 $timeout 破解它并删除 element.ready,但它仍然给了我子元素尚不存在的错误。我不想使用 $timeout,所以我正在寻找更实用的解决方案来解决我的问题。

另外,当我调用函数来创建新的第一级元素时,我尝试调用 jsPlumb 库,但它未定义 parentNode。我在 addChild 函数中将其注释掉。

ng-repeat ng-include=template2 上模板 3 中使用的指令

app.directive('vectorDrawDirective', function($timeout) {
    return function($scope, element, attrs) {
        //angular.element(element).css('color','blue');
        if ($scope.$last === true) {
            element.ready(function() {
            jsPlumb.connect({
                    source: $scope.firstlevel.parent_id,
                    target: $scope.firstlevel.id,
                });
                jsPlumb.repaintEverything();    
        })
        }
    }
});

这是我为帮助您可视化我要完成的内容而绘制的图表(请查看右上角的文字)

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-service jsplumb angularjs-controller


    【解决方案1】:

    ngInclude 提供了一个 onload 属性,该属性将在加载时评估表达式;这能满足你的需要吗?

    <div vector-draw-directive class="thirdlevel"
      ng-repeat="firstlevel in secondlevel.children"
      ng-include="'templateLevel2.html'" onload="loaded()">
    </div>
    

    非常基本的例子:http://jsfiddle.net/BinaryMuse/KRbdL/121/

    【讨论】:

    • 是的,我尝试使用它,但它仍然给我错误:无法读取未定义的属性'parentNode':jsfiddle.net/GeorgiAngelov/KRbdL/125 TypeError
    • 即使你在loaded里面设置了一个长的$timeout,还是不行。我对您用来真正有效调试的库不够熟悉。 =\
    • 我删除了库函数,以查看是否可以使用 document.getElementById 获得元素,但由于它返回 null ,因此这两个元素似乎都不存在......这是新的小提琴jsfiddle.net/GeorgiAngelov/KRbdL/143
    • 但是当使用 0 的 $timeout 时它可以正常工作,这是我在上一条评论中的观点:jsfiddle.net/BinaryMuse/KRbdL/151 指令通常会像这样使用 $timeout 处理任何延迟的 DOM 处理(或只需setTimeout 如果您不需要摘要循环)
    • 我明白了。我对使用 $timeout 感到很奇怪。我应该在哪里设置指令,但仍然可以访问第一级变量,因为我不能只将它注入指令中?
    【解决方案2】:

    您可以有点使用 window.requestAnimationFrame 回调来确定 Angular 何时完成对 DOM 的操作,如下所示:

    var fn = function () {
        var elm = document.getElementById('elementID');
    
        if(elm == null) {
            window.requestAnimationFrame(fn);
        } else {
            doSomething();
        }
    };
    fn();
    

    虽然这是一个 hack,所以使用风险自负

    【讨论】:

      猜你喜欢
      • 2021-06-15
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      相关资源
      最近更新 更多