<select ng-options =“”>和间接</select>的指令

时间:2013-08-16 12:44:04

标签: angularjs angularjs-directive

我在一个页面上有几个多选项,每个都有一些逻辑来填充来自服务器的多选项。我想将每个选项包装成一个指令。

在尝试将这些内容包装到Directives之前,我按照这样构建了每个:

的index.html

<select name="groups" ng-model="inputs.groups" ng-change="groupsChanged()" ng-options="g for g in allgroups" multiple></select>

controllers.js

在第一遍中,我从这里开始我的$ http电话。是的,我知道,不是最佳做法,但我想先证明这对我自己有用。

  $scope.loadSelect = function(_url) {
    $http({
      url: _url,
      method: 'POST',
      data: $scope.inputs,
      model: 'all' + _url
    }).success(function(data, status, headers, config) {
      $scope[config.model] = data;
    });
  };

  // Fill groups
  $scope.loadSelect('groups');

  // When groups change, reload other select fields that depend on groups
  $scope.groupsChanged = function() {
    $scope.loadSelect('categories');
    $scope.loadSelect('actions');
  }

现在我想将其迁移到指令。我看到两个主要挑战: 1.)如何将整套选项(例如现在的&#34; allgroups&#34;模型)封装到指令中? 2.)基于最初的实验,我尝试在模板中物理构建<select/>,但意识到我必须操纵DOM来物理地替换name,ng-model和ng-options。这导致我转向编译属性,但是a。感觉不对,而且b。)设置<select ng-options="x for x in allgroups" />在插入DOM之后实际上并没有重复。使用编译感觉不对;什么是正确的方法来解决这个问题?

这是我对该指令的第一次尝试看起来像这样。它没有真正起作用,我认为我不正确地做错了:

的index.html

<dimension ng-model="inputs.users" alloptions-model="allusers">Users</dimension>

directives.js

directive('dimension', function() {
  return {
    restrict: 'E',
    scope: {
      ngModel: '=',
      alloptionsModel: '='
    },
    template:
        '<div>' + 
          '<label ng-transclude></label>' +
          '<fieldset>' +
              '<div class="form-group">' +
                '<select ng-model="{{ngModel}}" ng-options="x for x in {{alloptionsModel}}" multiple class="form-control"></select>' +
              '</div>' +
           '</fieldset>' +
        '</div>',

    replace: true,
    transclude: true
  };
});

显然我还没有进入服务器加载部分,但我计划将其转换为指令中的控制器,并在服务中使用实际的$ http调用。

我觉得我走错了轨道。如果您有关于如何重新调整的建议,请提供帮助!

1 个答案:

答案 0 :(得分:1)

您的指令的主要问题是您不能在ngModelngOptions指令中使用胡子绑定,因为它们是直接计算的。您可以直接绑定到作用域属性(ngModel和alloptionsModel):

directive('dimension', function() {
  return {
    restrict: 'E',
    scope: {
      ngModel: '=',
      alloptionsModel: '='
    },
    template:
        '<div>' + 
          '<label ng-transclude></label>' +
          '<fieldset>' +
              '<div class="form-group">' +
                '<select ng-model="ngModel" ng-options="x for x in alloptionsModel" multiple class="form-control"></select>' +
              '</div>' +
           '</fieldset>' +
        '</div>',
    replace: true,
    transclude: true
  };
});

有关工作示例,请参阅this plunkr

修改 至于编译路线,它没有任何问题。当您需要动态创建模板时,这非常有用,当您到达select的项目模板时,这将非常明显。

compile: function(tElement, tAttrs) {
  var select = tElement.find('select'),
      value = tAttrs.value ? 'x.' + tAttrs.value : 'x',
      label = tAttrs.label ? 'x.' + tAttrs.label : 'x',
      ngOptions = value + ' as ' + label + ' for x in alloptionsModel';

      select.attr('ng-options', ngOptions);
}

// In the HTML file
<dimension ng-model="inputs.users" 
           alloptions-model="allusers"
           label="name">
  Users
</dimension>

我已使用编译功能更新了plunkr