5

我有一个指令,它的模板中有另一个指令。

<nv-select ng-model="from" ng-options="item.name as item for item in from"></nv-select>

在这里,我尝试将表达式传递给ng-options子指令。不幸的是,这总是给我以下错误

Error: Syntax Error: Token 'as' is an unexpected token at column ...

如果我将表达式放在ng-options子指令的select中,它就可以正常工作。我的nv-select指令如下所示:

function () {
  return {
    restrict: 'E', // restrict to elements
    replace: true,
    transclude: true,
    scope: {
      ngModel: "=",
      ngOptions: "&",
      placeholder: '@'
    },
    template: [
      '<div class="nv-select">',
        '<select ng-model="ngModel" ng-options="ngOptions" ng-transclude></select>',
        '<span class="icon suffix-icon-down">{{ text || placeholder }}</span>',
      '</div>'
    ].join(''),
    link: function (scope, elem, attr) {
      var select = elem.find('select'),
          copyValues = function (e) {
            if (e.options) {
              scope.text = angular.element(e.options[e.selectedIndex]).text();
            }
          };
      copyValues(elem[0]);
      elem.bind('click', function (event) {
        elem.toggleClass('active');
      });
      select.bind('change', function (event) {
        scope.$apply(function () {
          copyValues(event.target);
        });
      });
    }
  };
};

nv-select基本上只是 a 的包装器<select>以启用自定义样式。

传递表达式时是否需要特别考虑?我究竟做错了什么?

4

2 回答 2

0

让我们看看 ngOptions 是如何在 AngularJS 源代码中实现的。在这里我们可以找到表达式的正则表达式模式:

var NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*)$/

接着

    if (! (match = optionsExp.match(NG_OPTIONS_REGEXP))) {
      throw Error(
        "Expected ngOptions in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_'" +
        " but got '" + optionsExp + "'.");
    }

    var displayFn = $parse(match[2] || match[1]),
        valueName = match[4] || match[6],
        keyName = match[5],
        groupByFn = $parse(match[3] || ''),
        valueFn = $parse(match[2] ? match[1] : valueName),
        valuesFn = $parse(match[7]);

所以你可以使用它或编写新的。

于 2013-05-15T13:21:02.950 回答
0

有两件事浮现在脑海

  • ng-options 需要一个字符串,然后对其进行解析以提供相关位。您可以尝试推杆ng-options="{{ngOptions}}",看看是否可以解决问题。但是,您可能会遇到第二点:
  • 您已经创建了一个独立的范围,因此即使您使表达式正常工作,该范围也不会具有来自表达式的相关属性。

如果 {{}} 技巧不起作用,那么一旦您可以访问原始 ng-options 字符串(即在链接函数中),您似乎必须手动编译模板。

于 2013-05-15T16:51:03.380 回答