【问题标题】:How to set a default value in an AngularJS Directive Scope?如何在 AngularJS 指令范围中设置默认值?
【发布时间】:2015-10-28 15:18:46
【问题描述】:

在 AngularJS 中,我有以下场景,其中指令可以接受一个可选的布尔参数,默认情况下应该默认为 true只要未指定。。 p>

示例:

<my-directive data-allow-something="false">
    ... this works as expected as no default value should be set in this case ...
</my-directive>

<my-directive>
    ... but in this case i'd like allowSomething to equal true  ...
</my-directive>

我尝试了以下方法,但由于某种原因,true 值无法保持在 allowSomething 上。使它成为 '=?'可选的双向绑定不起作用,因为我传递的值应该是具体的真/假而不是字段引用。

angular.module('myApp').directive('myDirective') {
    ...
    controller: function($scope){
        if (!$scope.allowSomething)
            $scope.allowSomething = true;
    },
    ....
    scope: function(){
        allowSomething: '@'
    }
    ...
}

我确信应该有一个简单的方法来实现这一点,那么我错过了什么?

以下票证给出的解决方案:AngularJS directive with default options 不足以满足我的需要,因为 $compile 函数会阻止链接函数工作。另外,传入的布尔值不是引用类型,我不能给它一个双向绑定。

【问题讨论】:

  • 这可能是因为控制器在将隔离范围绑定到指令元素之前被实例化。因此,您设置的值将被从绑定中为指令创建的新范围覆盖。尝试在控制器的 $timeout 中设置默认值,或者尝试在链接函数中进行设置,或者调用指令控制器函数来设置链接函数的值。另请注意:您将 allowSomething 作为文本绑定,并且您将布尔值设置为默认值,您在属性中设置的内容将作为文本“false”到达?
  • 试图把它放在链接函数中,但没有成功。我也试图避免 $timeout 方法。我认为应该有一种更清洁的方法来做到这一点。

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

我认为你可以这样做:

 scope : true,
  link : function(scope, element, attrs){
    scope.allowSomething = $parse(attrs.allowSomething)(scope) || true;
    console.log(scope)
  }

【讨论】:

  • 这不起作用,因为我想保持指令的范围隔离,因为它应该是一个独立的可重用指令。
【解决方案2】:

我认为检查该值的更好方法是查找像这样的未定义值:

controller: function($scope){
    if (angular.isUndefined($scope.allowSomething))
        $scope.allowSomething = true;
}

我曾经遇到过同样的问题,这对我有用。我认为最好的方法是使用 Angular 的方法来处理事情。

【讨论】:

  • 如果你做if (!$scope.allowSomething) $scope.allowSomething = true;,它也会在你明确设置为假时设置为真。
【解决方案3】:

鉴于您的模板是

<body>
  <my-directive></my-directive>
  <!-- <my-directive allow-something="false"></my-directive> -->
</body>

然后您可以使用link(如果不需要与其他指令交互则首选)或controller

angular.module('myApp', [])
  .directive('myDirective', function() {
    return {
      scope: {},
      link: function(scope, element, attrs) {
        scope.allowSomething = ('allowSomething' in attrs) ? attrs.allowSomething : true;
      }, 
      template: '<div>allow:{{ allowSomething }}</div>'
    };
  });  

// 或

angular.module('myApp', [])
  .directive('myDirective', function() {
    return {
      scope: {
        allowSomething: '@'
      },
      controller: function($scope, $timeout) {
        $timeout(function() {
          if (angular.isUndefined($scope.allowSomething)) {
            $scope.allowSomething = true;
          }
        });
      },  
      template: '<div>allow:{{ allowSomething }}</div>'
    }; 
  });  

【讨论】:

    【解决方案4】:

    这就是我的做法:

    html:

    <my-directive allow-something="false"></my-directive>
    <my-directive></my-directive>
    

    指令:

    angular
    .module('app')
    .directive('myDirective', function() {
    
    var defaults = {
      allowSomething: true
    };
    
    return {
      restrict: 'E',
      templateUrl: '',
      scope: {},
      compile: function() {
        return {
          pre: function(scope, el, attrs) {
            scope.allowSomething = attrs.allowSomething || defaults.allowSomething;
          },
    
          post: function(scope, el) {
            // this is link
            // scope.allowSomething = default or whatever you enter as the attribute "false"
          }
        };
      }
    };
    }
    

    pre 在任何事情发生之前被触发,然后 post 就像链接功能。这让我可以根据我设置的属性做动态的事情。

    【讨论】:

    • 我认为这比公认的答案更干净,而且我还看到一些已知的插件使用这种模式和包含默认配置的 defaults 对象。
    猜你喜欢
    • 2013-12-27
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 2020-06-14
    相关资源
    最近更新 更多