4

我正在尝试将选择封装在自定义指令中,同时在指令声明中保留 ng-options 的使用。

目标是能够使用 my 指令在模板中保留 ng-options 的语法,但要正确地将其转发到指令内 select 的 ng-options。

那么更多的话,代码:

指令:

    angular.module('myApp').directive("selectField", function() {
    return {
        restrict: 'EA',
        replace: true,
        transclude : false,
        templateUrl : "/common/tpl/form/select-field.html",
        scope : {
            label   : "@",
            model   : "=",
            options : "&"
        }
    };
});

模板:

<div class="form-group">
    <label for="{{fieldId}}" class="col-lg-2 control-label">{{label | translate}}</label>
    <div class="col-lg-10">
        <select class="form-control" id="{{fieldId}}" ng-model="model" ng-options="{{options}}"></select>
    </div>
</div>

用法:

 <select-field label="myLabel" model="data.mySelectValue" options="p.nom for p in myOptions"></select-field>

而且......错误:

Error: [$parse:syntax] Syntax Error: Token 'for' is an unexpected token at column 7 of the expression [p.nom for p in preteurs] starting at [for p in preteurs].

我尝试使用 "&" 、 "=" 和 "@" 属性等选项,但似乎没有任何效果。

使用“=”和“&”时,角度会因给定错误而爆炸,而使用“@”属性时,表达式在指令范围内进行评估,这可以工作但不呈现任何选项,因为“myOptions”不存在于指令自己的范围内。 ..

我错过了什么吗?有没有办法做到这一点?

4

3 回答 3

1

我的解决方案依赖于我在angular ng-bind-html 的公认答案中找到的惊人的编译指令以及其中的指令......感谢 VKammerrer。这有点笨拙,但看看你刚刚发布的博客文章,我认为这可能是一个必要的邪恶。

设置如下:MyCtrl 和 MyView,其中包含

<select-field compile>

当然,您可以将 select-field 组合起来并编译成一个指令。

MyCtrl 在范围上定义了以下内容:

$scope.myOptions = [
    { value: 0, nom: 'a' },
    { value: 1, nom: 'b' }
];

MyView 具有以下 HTML:

<select-field options="myOptions" data="nom" compile></select-field>

selectField 的声明如下:

angular.module('myApp')
    .directive('selectField',
        function() {
            return {
                restrict: 'E',
                replace: true,
                transclude: false,
                templateUrl: 'scripts/directives/selectField.tmp.html',
                scope: {
                    options: '=',
                    data: '@'
                }
            };
        }
    );

selectField.tmp.html 如下:

<div>
    <select ng-model="something" ng-options="p.{{data}} for p in options"></select>
</div>

好的,这似乎对我有用,让我知道这是否有帮助/不起作用。

于 2013-09-27T18:07:33.623 回答
1

没有其他方法可以将选择列表和表达式作为单独的属性... http://blog.benkuhl.com/2013/08/how-to-use-ng-options-in-a-custom-directive-下拉菜单/

于 2013-09-27T17:49:34.310 回答
1

我找到了一个不涉及编译的替代方案。

在您的自定义指令中,您定义了 2 个绑定:

selectOptions: "<", // One way, it will contain the source array
selectOptionsExp: "@" // Literal string, it will contain the options expression

然后你可以在模板中使用这个 html:

<select ng-model="..." ng-options="{{ vm.selectOptionsExp }}"></select>

这是用法:

<my-directive ng-model="vm.selectedValue"
              select-options="vm.valuesArray"
              select-options-exp="item.label for item in vm.selectOptions track by item.id" />

请注意,“vm.selectOptions”是在内部范围内传递的,因此无需借助编译或转入即可使用。

此外,您可以使用可替换的标记来简化使用,该标记使读者清楚该变量不存在于当前范围内:

vm.getOptionsExp = function() { return vm.selectOptionsExp.replace("$options", "vm.selectOptions"); }
<select ng-model="..." ng-options="{{ vm.getOptionsExp() }}"></select>
<my-directive ng-model="vm.selectedValue"
                  select-options="vm.valuesArray"
                  select-options-exp="item.label for item in $options track by item.id" />

这可以扩展为包括使用单独的选项对自定义函数进行排序/过滤。

于 2017-10-10T10:27:02.957 回答