使用ng-repeat作为转换内容的自定义指令

时间:2015-11-25 14:24:49

标签: javascript jquery angularjs angularjs-directive

我正在制作一个包装multiselect jQuery plugin的指令。我的目标是将以下HTML转换为动态多选:

<select multiselect multiple ng-model="selected">
    <option>Static option 1</option>
    <option>Static option 2</option>
    <option ng-repeat="value in values">{{value}}</option>
</select>

请注意,可以直接添加选项或使用ng-repeat来迭代动态选项。

这是我写指令的方式:

app.directive('multiselect', function () {
    return {
        restrict: 'A',
        scope: {
            model: '='
        },
        transclude: true,
        require: 'ngModel',
        link: function (scope, element, attrs, controller, transclude) {
            transclude(function (clone) {
                element.append(clone);
                $(element).multiselect();
            });
        }
    };
});

问题在于,当指令工作并用jQuery multiselect插件替换HTML时,它只显示静态提供的选项。使用ng-repeat创建的选项不会被插件显示,即使它们可以在Angular呈现的HTML源中看到。在插件创建multiselect之后,似乎将transclude克隆附加到元素。

Here's the JSFiddle重现了这个问题。

我的理解是否正确?可能是这种行为的原因是什么?

2 个答案:

答案 0 :(得分:3)

我不确定为什么你的方式不起作用,但用option替换ngRepeat标记+ ngOptions似乎就是这样做的。

<select multiselect multiple ng-model="selected" ng-options="value for value in values">
  <option>Static option 1</option>
  <option>Static option 2</option>  
</select>

Working JSFiddle

答案 1 :(得分:0)

对于遇到同样问题的人来说,这里有一个完整的链接功能,我用它来获得成功的结果。

link: function (scope, element, attrs, controller, transclude) {
  transclude(function (clone) {
    element.append(clone);
  });
  $timeout(function() {
    element.multiselect();
  });
}

不要忘记将$timeout注入指令。

.directive('multiselect', function ($timeout) {

transclude函数负责附加ng-repeat指令生成的内容。但是,ng-options指令也适用,在这种情况下,动态选项会在静态选项之前显示。只使用$timeout包裹多选。

我也开始挖掘,以便了解为什么使用超时功能实际上有助于在this answerthis blog post上找到John Resig的一些合理解释。