15

快速示例:

有一个路由参数 (/Home/:isLoggedIn) 等于 true 或 false。(/Demo/#/Home/false) 和一个控制器属性

this.loggedIn = this.routeParams.loggedIn;

我有一个视图(Home.html),它有两个元素,每个元素都有一个 ng-if 属性。

<div ng-if="home.loggedIn">
    Logged In!
</div>
<div ng-if="!home.loggedIn">
    Not Logged In...
</div>

如果我导航到 /Demo/#/Home/true 则显示第一个元素而第二个不显示。如果我导航到 /Demo/#/Home/false 则第一个元素不显示也不显示第二个元素。

我希望 !home.loggedIn 参数在 loggedIn 的值实际上为 false 时评估为 true。

这里有什么建议吗?

4

2 回答 2

31

很明显,这个问题的根源在于它routeParams.loggedIn是一个字符串。

所以解决方案很明显:

// Change that:
this.loggedIn = this.routeParams.loggedIn;

// To this:
this.loggedIn = this.routeParams.loggedIn === 'true';

但为什么会有奇怪的行为?
为什么在loggedIn“假”时工作不显示任何内容?

好吧,这就是为什么:

ngIf指令使用以下toBoolean()函数将其值转换为布尔值:

function toBoolean(value) {
  if (typeof value === 'function') {
    value = true;
  } else if (value && value.length !== 0) {
    var v = lowercase("" + value);
    value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
  } else {
    value = false;
  }
  return value;
}

如果将字符串传递给toBoolean()它,则将其转换为小写并检查(除其他外)它是否等于 'false'(在这种情况下它返回false)。这与将任何非空字符串解释为true转换为布尔值时的默认 JavaScript 实现不同。

因此,让我们检查两个ngIfs 的两种情况:

  1. loggedIn === 'true'

    ngIf1 评估home.loggedIn--> 'true' (string)
    ngIf1 通过toBoolean()
    toBoolean('true')返回true传递这个值(因为它看到的字符串不能与任何被认为是假的字符串匹配)
    ngIf1 呈现它的内容

    ngIf2 评估!home.loggedIn<=> !'true'--> false (boolean)
    (发生这种情况是因为任何非空字符串碰巧评估为 true)
    ngIf2 通过toBoolean()
    toBoolean(false)返回false
    传递此值 ngIf2 不呈现其内容

  2. loggedIn === 'false'

    ngIf1 评估home.loggedIn--> 'false' (string)
    ngIf1 通过toBoolean()
    toBoolean('false')返回false传递这个值(因为它看到一个被认为是假的字符串
    ngIf1 不呈现它的内容

    ngIf2 评估!home.loggedIn<=> !'false'--> false (boolean)
    (发生这种情况是因为任何非空字符串碰巧评估为 true)
    ngIf2 通过toBoolean()
    toBoolean(false)返回false
    传递此值 ngIf2 不呈现其内容

所以,这解释了“奇怪”的行为(希望以一种可以理解的方式)。

于 2014-04-09T16:24:37.797 回答
1

问题可能是 home.loggedIn 是一个字符串,当传递给 ng-if 它可能正在评估并执行从字符串到布尔的转换以将值“false”转换为 false 时。在传递值之前的表达式评估中,如果您有 !"false" 实际上为假,因为任何字符串为真,否定它变为假。

于 2014-04-09T16:09:14.133 回答