【问题标题】:How to bind boolean values in angular directives?如何在角度指令中绑定布尔值?
【发布时间】:2013-08-02 10:16:18
【问题描述】:

我想将一些布尔属性绑定/设置到指令。但我真的不知道如何做到这一点并实现以下行为。

假设我想为一个结构设置一个标志,假设一个列表是否可折叠。我有以下 HTML 代码:

<list items="list.items" name="My list" collapsable="true"></list>

items 是双向绑定的,name 只是一个属性

我希望 collapsable 属性在列表的 $scope 中可用,方法是传递一个值(true、false 或其他),或者双向绑定

<list items="list.items" name="{{list.name}}" collapsable="list.collapsed"></list>

我正在开发一些 UI 组件,我想提供多种与它们交互的方式。也许,随着时间的推移,有些人想通过将对象的属性传递给属性来了解该组件的状态,无论是折叠还是未折叠。

有没有办法做到这一点?如果我误解了什么或我错了,请纠正我。

谢谢

【问题讨论】:

  • 在传递直接布尔值truefalse 时,将属性设置为与'=' 绑定的双向将不起作用,因为我无法将范围的值设置为另一个值。例如$scope.collapsable = false;
  • 你会在运行时更改可折叠属性值还是在deslaration时保持不变
  • 如果值不会改变,那么只需使用 attrs["collapsable"]
  • 正如我所说,值可能会在控制器内发生变化

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

您可以为布尔值配置自己的单向数据绑定行为,如下所示:

link: function(scope, element, attrs) {

    attrs.$observe('collapsable', function() {

        scope.collapsable = scope.$eval(attrs.collabsable);
    });

}

在此处使用 $observe 意味着您的“监视”仅受属性更改的影响,如果您直接更改指令中的 $scope.collapsable 则不会受到影响。

【讨论】:

  • 我发现在这里使用 $scope/$element/$attrs 名称令人困惑,因为链接没有注入,只有位置参数。所以范围、元素、属性会更合适。
  • scope.$eval()和javascript原生的eval()函数有区别吗?
  • @Bloke 这是一个您可能会发现有用的 SO 问题。 stackoverflow.com/questions/15671471/…
【解决方案2】:

在设置双向绑定的指令上创建一个范围:

app.controller('ctrl', function($scope)
{
    $scope.list = {
        name: 'Test',
        collapsed: true,
        items: [1, 2, 3]
    };
});

app.directive('list', function()
{
    return {
        restrict: 'E',
        scope: {
            collapsed: '=',
            name: '=',
            items: '='
        },
        template:
            '<div>' +
                '{{name}} collapsed: {{collapsed}}' +
                '<div ng-show="!collapsed">' +
                    '<div ng-repeat="item in items">Item {{item}}</div>' +
                '</div>' +
                '<br><input type="button" ng-click="collapsed = !collapsed" value="Inside Toggle">' +
            '</div>'
    };
});

然后将选项作为属性传递:

<list items="list.items" name="list.name" collapsed="list.collapsed"></list>

http://jsfiddle.net/aaGhd/3/

【讨论】:

  • 绝对有效!但我也希望能够将collapsed 属性设置为布尔值,truefalse
【解决方案3】:

不能传递字符串truefalse作为属性值,也支持传递list.collapsed等作用域属性作为双向绑定的属性值。您必须选择一种方式或其他方式。

这是因为在使用隔离作用域时,您只能指定一种方式来解释指令中的属性值。

我想你可以在你的指令中使用=,如果attrs.collapsable 设置为truefalse,也可以检查你的链接函数:如果是这样,那么你知道传递了一个布尔值,并且如果没有,请使用双向数据绑定。但这很 hacky。

【讨论】:

    【解决方案4】:

    我知道我在这方面迟到了一年,但您实际上可以通过使用链接功能 (https://docs.angularjs.org/guide/directive) 来做到这一点。签名如下所示:

    function link(scope, element, attrs) { ... } 
    

    那个 attrs 对象将被传入的原始值填充。所以你可以说 if (attrs.collapsed == 'true') { ... } 或类似的。

    【讨论】:

    • 这行不通。属性内的所有值都是字符串类型。所以如果你要设置collapsed="false",然后检查(attrs.collapsed)是否为true,因为字符串"false"是truthy
    • 确实如此。我用一个简单的“真”字符串测试更新了这个例子。我认为它确实解决了问题的意图。
    【解决方案5】:

    由于 Angular 1.3 attrs.$observe 似乎也会触发未定义的属性,因此如果您想考虑未定义的属性,您需要执行以下操作:

    link: function(scope, element, attrs) {
        attrs.$observe('collapsable', function() {
          scope.collapsable = scope.$eval(attrs.collapsable);
          if (scope.collapsable === undefined) {
            delete scope.collapsable;
          }
        });
      },
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-22
      • 2011-01-27
      • 2015-06-19
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多