如何使用指令设置其他指令?

时间:2014-02-10 22:50:11

标签: javascript angularjs

我在控制器范围内有一个对象,其中包含输入的一些演示数据:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.settings = {
    value: 'xxx',
    required: true,
    show: true,
    readonly: false
  };
});

在实际应用程序中,这是从服务器加载的较大对象的一部分。我创建了一个指令,它将此表示对象作为输入并附加必要的指令:

app.directive('fieldSettings',
  [/*$injectables*/
  function (/*$injectables*/) {
    return {
      priority: 100,
      restrict: 'A',
      scope: {
        fieldSettings: '='
      },
      compile: function (el, attrs) {
        return function (scope, iElement, iAttrs) {
          iAttrs.$set('ng-model', 'fieldSettings.value');
          iAttrs.$set('ng-show', 'fieldSettings.show');
          iAttrs.$set('ng-required', 'fieldSettings.required');
          iAttrs.$set('ng-readonly', 'fieldSettings.readonly');
        }
      }
    };
  }
]);

正如此plunk所示,添加了属性但未应用逻辑。根据angular的文档,我尝试应用的指令优先级为0input指令的优先级为100。我将我设置为100,但无论我为其选择的值如何,此值似乎都没有影响。

我想要

<input field-settings="settings" />

的行为类似于

<input ng-model="settings.value" ng-show="settings.show" ng-required="settings.required" ng-readonly="settings.readonly" />

但确实是

<input ng-model="fieldSettings.value" ng-show="fieldSettings.show" ng-required="fieldSettings.required" ng-readonly="fieldSettings.readonly" />

其中fieldSettings是指令的局部范围变量绑定到MaintCtrl的局部范围变量settings

1 个答案:

答案 0 :(得分:2)

只需添加属性而不进行编译就不会做任何事情。

我的回答类似:

这是一个掠夺者:http://plnkr.co/edit/8kno6iwp3hH5CJFQt3ql?p=preview

工作指令:

app.directive('fieldSettings',
  ['$compile',
  function ($compile) {
    return {
      restrict: 'A',
      scope: {
        fieldSettings: '='
      },
      priority: 1001,
      terminal: true,
      compile: function(tElm,tAttrs){
        tElm.removeAttr('field-settings')
        tElm.attr('ng-model', 'fieldSettings.value');
        tElm.attr('ng-show', 'fieldSettings.show');
        tElm.attr('ng-required', 'fieldSettings.required');
        tElm.attr('ng-readonly', 'fieldSettings.readonly');
        var fn = $compile(tElm);
        return function(scope){
          fn(scope);
        }
      }
    };
  }