web-dev-qa-db-ja.com

AngularJS ng-ifディレクティブのパラメーターを無効にするにはどうすればよいですか?

簡単な例:

Trueまたはfalseに相当するルーティングパラメータ(/ Home /:isLoggedIn)があります。 (/ Demo /#/ Home/false)とコントローラーのプロパティ

this.loggedIn = this.routeParams.loggedIn;

それぞれng-if属性を持つ2つの要素を持つビュー(Home.html)があります。

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

/ Demo /#/ Home/trueに移動すると、最初の要素が表示され、2番目の要素は表示されません。/Demo /#/ Home/falseに移動すると、最初の要素が表示されませんNORは2番目の要素を表示します。

!home.loggedInパラメータは、loggedInの値が実際にはfalseのときにtrueと評価されることを期待しています。

ここで何かアドバイスはありますか?

15
beauXjames

彼の問題が_routeParams.loggedIn_が文字列であるという事実にその根があることは明らかです。

したがって、解決策は非常に明白です。

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

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

しかし、なぜ奇妙な振る舞いなのか?
loggedInが「false」の場合、なぜ何も表示されないのはなぜですか?

さて、ここに理由があります:

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の2つのケースを調べてみましょう。

  1. _loggedIn === 'true'_

    ngIf1は_home.loggedIn_-> 'true'(文字列)を評価します
    ngIf1はtoBoolean()を介してこの値を渡します
    toBoolean('true')trueを返します(偽と見なされる文字列と一致しない文字列が表示されるため)
    ngIf1はそのコンテンツをレンダリングします

    ngIf2は_!home.loggedIn_ <=> _!'true'_-> false(ブール値)を評価します
    (空でない文字列がたまたまtrueと評価されるために発生します)
    ngIf2はtoBoolean()を介してこの値を渡します
    toBoolean(false)falseを返します==
    ngIf2はコンテンツをレンダリングしません

  2. _loggedIn === 'false'_

    ngIf1は_home.loggedIn_-> 'false'(文字列)を評価します
    ngIf1はtoBoolean()を介してこの値を渡します
    toBoolean('false')falseを返します(偽と見なされる文字列が表示されるため)
    ngIf1はコンテンツをレンダリングしません

    ngIf2は_!home.loggedIn_ <=> _!'false'_-> false(ブール値)を評価します
    (空でない文字列がたまたまtrueと評価されるために発生します)
    ngIf2はtoBoolean()を介してこの値を渡します
    toBoolean(false)falseを返します==
    ngIf2はコンテンツをレンダリングしません

したがって、これは「奇妙な」動作を説明します(うまくいけば理解できる方法で)。

29
gkalpak

問題はおそらくhome.loggedInが文字列であり、ng-ifに渡された場合、文字列からブール値への変換を評価および実行して、値「false」をfalseに取得することです。文字列がtrueであるために実際にはfalseである! "false"がある場合、値が渡される前の式の評価では、それを否定するとfalseになります。

1
shaunhusain