【问题标题】:How do I use a directive to set other directives?如何使用指令来设置其他指令?
【发布时间】:2014-03-08 12:17:16
【问题描述】:

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

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 的文档,我尝试应用的指令的优先级为 0,而 input 指令的优先级为 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

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

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

    我的类似回答:

    这里是一个笨蛋: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);
            }
          }
        };
      }
    

    【讨论】:

    • 是否有理由使用elm.attr 而不是attrs.$set
    • 哦! tElm.removeAttr('field-settings') 是关键。我曾尝试过$compile,但得到了Maximum call stack size exceeded,现在这似乎很明显,因为它会尝试重新应用字段设置指令并陷入循环!
    • @ogc-nick 在这种情况下它们的工作方式相同。 attrs.$set 不仅具有获取/设置属性的功能。
    • @ogc-nick 终端和高优先级对于这种自编译模式也非常重要。
    • 将优先级设为100就够了吗? 100 是输入的优先级,据我所知,我添加的指令的优先级为 0。我以前没有听说过终端,尽管我必须查一下。我应该使用它吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 2015-06-24
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多