我该如何确定ng-options何时完成更新DOM?

5
我将尝试使用指令在我的应用程序中实现jQuery多选插件。这是选择元素:
<select multiple 
        ng-model="data.partyIds" 
        ng-options="party.id as party.name for party in parties" 
        xs-multiselect="parties">
</select>

模型parties是通过$http加载的。多选插件解析select中的option元素并生成漂亮的多选框。

有没有办法检测select元素何时填充了选项,以便我可以告诉多选插件更新其数据?

这是我的指令:

machineXs.directive("xsMultiselect", function() {
    return {
        restrict: "A",
        require: '?ngModel',
        link: function(scope, element, attrs, ngModel) {
            element.multiselect().multiselectfilter();
            scope.$watch(scope[attrs["xsMultiselect"]], function() {
                // I tried watching but it doesn't help
                element.multiselect('refresh');
                element.multiselectfilter("updateCache");
            });
        }
    }
});

在你的 $watch 中,尝试调用 $timeout -- 也就是将多选内容放在一个 timeout 回调函数中。这可能会给 ng-options 指令一个运行的机会,并将选项添加到 DOM 中。 - Mark Rajcok
这些可能会给你一些灵感:Lucas在指令中包装了chosen博客文章;whiteb0x在指令中包装了select2:http://stackoverflow.com/questions/15212530/select2-tagging-input-loses-value-angularjs - Mark Rajcok
再看一遍,$watch 应该改为 scope.$watch(attrs.xsMultiselect, ...) - Mark Rajcok
是的,这个可以工作。我以为我必须观察引用而不是作用域属性名称 :) 但是它有多“安全”?如果选择有400个选项,它是否会以同样的方式工作? - lucassp
我还没有尝试过不使用$timeout。 - lucassp
显示剩余5条评论
1个回答

5

如评论中所讨论的那样,使用

scope.$watch(attrs.xsMultiselect, ...)

我不确定手表何时触发,与ngOptions何时更新DOM。如果您发现手表触发太早,可以尝试使用$evalAsync()或$timeout()。$evalAsync将稍后执行,但在DOM呈现之前。$timeout()将稍后执行,在DOM呈现后。

scope.$watch(attrs.xsMultiselect, function() {
   scope.$evalAsync(function() {
      element.multiselect('refresh');
      element.multiselectfilter("updateCache");
   });
});

或者,在DOM渲染后:
scope.$watch(attrs.xsMultiselect, function() {
   $timeout(function() {
      element.multiselect('refresh');
      element.multiselectfilter("updateCache");
   });
});

这在Angular 1.5.6中不起作用,它会在DOM更新之前触发。有什么想法?! - Campbeln

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接