Angular 带有 bool 属性的指令传递字符串而不是 bool

Angular directive with bool attribute passing string instead of bool

我正在尝试创建一个指令来禁用容器内的所有输入元素,但我在使用该属性时遇到了问题。这就是我得到的指令

指令

angular.module('common')
    .directive('bdDisabled', [function () {
            return {
                restrict: 'A',
                scope: {
                    bdDisabled: '='
                },
                link: function (scope, element, attrs) {
                    attrs.$observe('bdDisabled', function(newValue, oldValue) {
                        if (newValue !== oldValue) {
                            if (newValue) {
                                element.find('input, select, button, submit, textarea').prop('disabled', 'disabled');
                            } else {
                                element.find('input, select, button, submit, textarea').removeProp('disabled');
                            }

                        }
                    });
                }
            };
        }
    ]);

这就是我想要的使用方式:

<div class="cg-content cg-shadow" bd-disabled="isLoading">

问题是属性值是字符串 isLoading 而不是值。

如果我将它用大括号括起来,它就会损坏,并且我会在控制台中收到错误消息。 如果我将它用大括号括起来并将范围更改为“@”而不是“=”,它就可以工作。但它发送的是字符串 "true" 或 "false",而不是布尔值。

我哪里错了?

您不必将 observe 与“=”一起使用。详情见下面link,我相信它比文档更强大。

What is the difference between '@' and '=' in directive scope in AngularJS?

就您的代码而言,我会仔细检查 isLoading 变量以确保它是一个布尔值。

正如我在评论中建议的那样,我会将 attrs.$observe 切换为 scope.$watch。根据个人喜好,我也会使用函数表达式而不是字符串,因为如果您使用的是打字稿(或将使用),如果 属性 更改,您将收到通知,其中字符串将可能保持原样:

scope.$watch(function () {
      return scope.bdDisabled;
      }, 
      function (newVal, oldVal) {
          ...
      }
);

当您将范围定义从“=”更改为“@”时,您只想将其作为字符串传递,而不是双向绑定模式。当然,您确实可以将其转换为 true,例如:

var myBool = Boolean("false"); // === true

var myBool = Boolean("true"); // === true

但要小心,因为任何字符串都可以被视为 true,例如:

var myBool = Boolean("foo"); // === true