如何在 AngularJS 指令范围中设置默认值?

Posted

技术标签:

【中文标题】如何在 AngularJS 指令范围中设置默认值?【英文标题】:How to set a default value in an AngularJS Directive Scope? 【发布时间】: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 方法。我认为应该有一种更清洁的方法来做到这一点。 Angular directive with default options的可能重复 【参考方案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 对象。

以上是关于如何在 AngularJS 指令范围中设置默认值?的主要内容,如果未能解决你的问题,请参考以下文章

使用Angularjs在选择下拉菜单中设置默认值

在 AngularJs 中设置动态范围变量 - scope.<some_string>

AngularJS - 在 ng-repeat 中设置默认值 [重复]

默认日期设置不起作用Angularjs指令

Angularjs - 如何在服务中设置模块值?

AngularJS指令隔离范围和父范围