AngularJS:如何在指令的templateURL中使用ng-repeat?

时间:2014-04-27 06:10:42

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

我创建了一个指令来显示"下拉"。以下是我使用的代码

HTML

<km-sselect km-left-title="Left" km-right-title="Right" km-model="sdsd" km-option="['AA','BB']"></km-sselect>

指令

app.directive('kmSselect', function($parse) {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: 'select.html',
    scope:true,

    link: function(scope, element, attr) {
      scope.leftTitle='';
            if(angular.isUndefined(attr.kmLeftTitle)) {
              scope.leftTitle='';
            }
            else {
               scope.leftTitle=attr.kmLeftTitle+"  ";
            }
      scope.rightTitle='';
            if(angular.isUndefined(attr.kmRightTitle)) {
              scope.rightTitle='';
            }
            else {
               scope.rightTitle="  "+attr.kmRightTitle ;
            }

      var str1="n in ";
      var str2=attr.kmOption;
      var str3=attr.kmModel;
      scope.model=attr.kmModel;
      scope.repeat=str1.concat(str2);
      scope.result=str1.concat(str3);

    }
  }
})

Select.html

<div>
  <div ng-switch on="format">
    <div ng-switch-when="kmForm">
      <div>
        <div class="floatLeft">
          {{leftTitle}}
          Repeat={{repeat}}
      </div>

      <select multiple ng-model="fdg" ng-click="testfunc(attrs.kmModel)">
        <option ng-repeat={{repeat}} value="{{n}}">{{n}}</option>
      </select>
    </div>{{rightTitle}}</div>
  </div>
  <div ng-switch-when="kmPreview">
    <div>
      <div class="floatLeft">
        title
        result
      </div>
      <div class="floatLeft box">
      <ul>
        <li ng-repeat="result" class="hrline">{{n}}</li>
      </ul>
      </div>
    </div>
  </div>
</div>

我没有在&#34; Dropdown&#34;中填充值。

谁能告诉我哪里出错了

3 个答案:

答案 0 :(得分:1)

您尝试解决问题的方式看起来很复杂,可能难以实施。

为什么不创建隔离范围? (该指令看起来像是可重用的,因此使用隔离范围来防止意外后果。)

在这种情况下,您可以双向绑定选项和模型,然后将它们传递给ng-model和指令内模板内的ng-select。

答案 1 :(得分:0)

如果您使用选择,则需要使用指令ng-option作为循环功能而不是ng-repeat。查看文档here

<select multiple ng-model="fdg" ng-click="testfunc(attrs.kmModel)" ng-options={{repeat}}></select>

然而,这有一个有趣的气味,我认为它不会起作用,因为在{{repeat}}有机会被渲染之前,ng-options会被触发。

我建议将这个选择拉到自己的指令中,这样它就可以同时包含所有内容,这可能会解决潜在的代码味道。

答案 2 :(得分:0)

release转换为n in ['AA','BB']之前,ng-repeat已经确定它有invalid expression

解决方案是在链接函数中为集合创建范围值,然后您的模板可以在标准ng-repeat表达式中引用它。为此,请使用$eval将字符串中的属性转换为对象。

scope.kmOption = scope.$eval(attr.kmOption);

现在你可以在select.html中编写一个典型的表达式:

<option ng-repeat="n in kmOption" value="{{n}}">{{n}}</option>

并且,正如其他人所说的那样,通常情况下ng-options使用select会更好,但同样需要修复:

<select multiple ng-model="$parent.kmModel" ng-options="n for n in kmOption"></select>

<强>更新
如果您重写指令,则可以避免使用link函数$eval选项:

app.directive('kmSselect', function($parse) {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: 'select.html',
    scope: {
      kmModel: '=',
      format: '=',
      kmLeftTitle: '@',
      kmRightTitle: '@',
      kmOption: '@'
    }
  }
})

更改模板以插入kmOption

<select ng-model="$parent.kmModel" ng-options="n for n in {{kmOption}}"></select>

如果您想亲自试用代码here is a working demo on Plunkr

旁注
实际上,我很惊讶这是有效的,因为ng-repeat不允许类似的使用(如上所述):ng-repeat="n in {{kmOption}}"