【问题标题】:Angular directive with bool attribute passing string instead of bool带有 bool 属性的 Angular 指令传递字符串而不是 bool
【发布时间】:2016-03-31 15:27:47
【问题描述】:

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

指令

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”,而不是布尔值。

我哪里出错了?

【问题讨论】:

  • 如果将attrs.$observe 切换为scope.$watch 会发生什么?
  • 我试试看,等一下
  • 使用 @ 是为了传递一种方式绑定字符串。您可以将其解析为布尔值,否则将其传递为 =,这将是双向绑定对象
  • @OmriAharon,做到了。谢谢。请建议它作为答案,我会接受。

标签: javascript angularjs angular-directive


【解决方案1】:

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

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

【讨论】:

  • 抱歉,我看不出与在您的 $watch 和 TypeScript 中使用该函数的相关性?有或没有都有可能。
  • @ste2425 我说的是,例如,如果您使用 Typescript,并将编译器设置为在构建 JS 错误时失败,那么更改您正在查看的变量名称将导致构建如果您在函数中引用变量,则失败(因为该变量将不再为人所知)。如果它只是写在字符串中,即'bdDisabled',那么编译仍然会成功。这只是一个例子。
  • $watch 用于查看模型或范围属性。例如,在您的情况下 bd-disabled="isLoading" , scope.$watch(attrs.bdDisabled) 或 scope.watch('isLoading') 。 $observe 仅在您想使用插值观察 DOM 属性的值变化时才起作用,例如 firstName= "Mr : {{firstName}}" 在您的指令中使用 attrs.$observe('firstName') 在这种情况下 $scope.$手表不工作。
【解决方案2】:

您不必使用带有“=”的观察。有关详细信息,请参阅以下链接,我相信它比文档更强大。

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

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

【讨论】:

  • 嗨,它绝对是一个布尔值。将其作为字符串处理的原因是@,它在传入时将其转换为字符串。
  • @Smeegs 我的错误,我在阅读时正在查看您的代码。
【解决方案3】:

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

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

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

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

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

【讨论】:

  • 布尔('false')为真
  • 同意,我的错,我只是忘记了那个 JS 问题,我的意图只是显示 AngularJS 的范围定义
  • 已修复,当您针对字符串 var myBool = Boolean("foo"); // === true 测试真值时要小心。考虑查看 MDN 文档developer.mozilla.org/en/docs/Glossary/Truthy
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 2014-04-29
相关资源
最近更新 更多