Angularjs ng-modelがng-if内で機能しない


206

これが問題を示すフィドルです。 http://jsfiddle.net/Erk4V/1/

ng-ifの内部にng-modelがあると、モデルが期待どおりに動作しません。

これがバグなのか、それとも正しい使い方を誤解しているのか、気になります。

<div ng-app >
    <div ng-controller="main">

        Test A: {{testa}}<br />
        Test B: {{testb}}<br />
        Test C: {{testc}}<br />

        <div>
            testa (without ng-if): <input type="checkbox" ng-model="testa" />
        </div>
        <div ng-if="!testa">
            testb (with ng-if): <input type="checkbox" ng-model="testb" />
        </div>
        <div ng-if="!someothervar">
            testc (with ng-if): <input type="checkbox" ng-model="testc" />
        </div>

    </div>
</div>

6
回避策として、ng-ifの代わりにng-show = "CONDITION"を使用できます。うまくいくはずです。
Hari Das

私はこれがもはや問題にならないと思いますcontrollerAsか?
jamiebarrow

暗黙のディレクティブを使用するときに同じ問題が発生し、ディレクティブの周りに要素scope:falseを追加しましたng-if-スコープは最初にバインドされましたが、ウォッチャーがスコープ値の1つを更新した後、スコープが分離されました...
Aprillion

回答:


223

ng-if他のディレクティブと同様に、ディレクティブは子スコープを作成します。以下のスクリプト(またはこのjsfiddle)を参照してください

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.min.js"></script>

<script>
    function main($scope) {
        $scope.testa = false;
        $scope.testb = false;
        $scope.testc = false;
        $scope.obj = {test: false};
    }
</script>

<div ng-app >
    <div ng-controller="main">
        
        Test A: {{testa}}<br />
        Test B: {{testb}}<br />
        Test C: {{testc}}<br />
        {{obj.test}}
        
        <div>
            testa (without ng-if): <input type="checkbox" ng-model="testa" />
        </div>
        <div ng-if="!testa">
            testb (with ng-if): <input type="checkbox" ng-model="testb" /> {{testb}}
        </div>
        <div ng-if="!someothervar">
            testc (with ng-if): <input type="checkbox" ng-model="testc" />
        </div>
        <div ng-if="!someothervar">
            object (with ng-if): <input type="checkbox" ng-model="obj.test" />
        </div>
        
    </div>
</div>

したがって、チェックボックスtestbは子スコープの内側を変更しますが、外側の親スコープは変更しません。

親スコープのデータを変更する場合は、最後に追加したdivのように、オブジェクトの内部プロパティを変更する必要があることに注意してください。


1
メインコントローラー関数内からng-ifのスコープにどのようにアクセスしますか?少しイライラします。これの理由は何ですか?
ジャスティンカールソン

気にしないでください、@ szaはその^質問に答えました。私が問題を抱えていた正確な理由を説明するので、私はこの答えを正しいとマークします。
ジャスティンカールソン

21
これは、例で指摘されているように、スコーププロパティを直接変更するのではなく、スコープで包含オブジェクトを使用するのが一般的である理由の1つです。この制限$scope.obj = {...}ng-model="obj.someProperty"克服しています。
wulftone 2014年

204

$parentこのように親スコープで定義されたモデルを参照するために使用できます

<input type="checkbox" ng-model="$parent.testb" />

16
それからng-model="$parent.$parent.foo私はすでにスコープ内にいるので持っていますng-repeat-これは本当に最良の方法ですか?
2013年

4
これは本当に混乱しています。何故ですか?なぜng-hideは独自のスコープを持たないのですか?
ドミニクゴルターマン2014

5
@Gaulについて:おそらくng-hide / ng-showは現在のDOMで動作し、CSSクラスを追加/削除するだけですが、ng-if / ng-switch / ng-repeatはDOMをすべて操作して余分な状態を追跡します。賢明なようです。
trisweb 2014

4
賢明は私が使う言葉ではありません
Jonathan Dumaine 2014

3
オブジェクトを元のスコープに追加し、そのオブジェクトのプロパティを変更します。例:ng-model = "myObject.property"。これは、すべてのスコープ/ $ parent inanityを回避します。詳しくは、Googleの「角ドットルール」をご覧ください。
Asmor

50

ngHide (またはngShow)ディレクティブを使用できます。ngIfのように子スコープを作成しません。

<div ng-hide="testa">

3
なぜ子ngIfスコープを作成するのですか?私には非常に奇妙に思えます。
freeall

5
zsong回答のコメントに注意してください。ng-hideHTML構造は変更されません。それは単にCSSスタイルを変更します。ng-ifより複雑です。条件に応じてHTMLパーツを削除および挿入します。状態を格納する子スコープを作成します(少なくとも、非表示のHTMLパーツを格納する必要があります)。
Vasiliy Kevroletin 2015年

うん、私のために働きなさい
ベイシット

7

他にも多くの場合にこれがありましたが、内部的には、コントローラー/ディレクティブのラッパーを常に用意しておく必要があるため、考える必要がないようにしました。これがラッパーの例です。

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.min.js"></script>

<script>
    function main($scope) {
        $scope.thisScope = $scope;
        $scope.testa = false;
        $scope.testb = false;
        $scope.testc = false;
        $scope.testd = false;
    }
</script>

<div ng-app >
    <div ng-controller="main">

        Test A: {{testa}}<br />
        Test B: {{testb}}<br />
        Test C: {{testc}}<br />
        Test D: {{testd}}<br />

        <div>
            testa (without ng-if): <input type="checkbox" ng-model="thisScope.testa" />
        </div>
        <div ng-if="!testa">
            testb (with ng-if): <input type="checkbox" ng-model="thisScope.testb" />
        </div>
        <div ng-show="!testa">
            testc (with ng-show): <input type="checkbox" ng-model="thisScope.testc" />
        </div>
        <div ng-hide="testa">
            testd (with ng-hide): <input type="checkbox" ng-model="thisScope.testd" />
        </div>

    </div>
</div>

これが役立つことを願っています、Yishay


3

はい、ng-hide(またはng-show)ディレクティブは子スコープを作成しません。

これが私の練習です:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.min.js"></script>

<script>
    function main($scope) {
        $scope.testa = false;
        $scope.testb = false;
        $scope.testc = false;
        $scope.testd = false;
    }
</script>

<div ng-app >
    <div ng-controller="main">

        Test A: {{testa}}<br />
        Test B: {{testb}}<br />
        Test C: {{testc}}<br />
        Test D: {{testd}}<br />

        <div>
            testa (without ng-if): <input type="checkbox" ng-model="testa" />
        </div>
        <div ng-if="!testa">
            testb (with ng-if): <input type="checkbox" ng-model="$parent.testb" />
        </div>
        <div ng-show="!testa">
            testc (with ng-show): <input type="checkbox" ng-model="testc" />
        </div>
        <div ng-hide="testa">
            testd (with ng-hide): <input type="checkbox" ng-model="testd" />
        </div>

    </div>
</div>

http://jsfiddle.net/bn64Lrzu/


0

あなたはこのようにそれを行うことができ、あなたはmod関数が完璧に機能しますあなたがコードペンが欲しいかどうか私に知らせてください

  <div ng-repeat="icon in icons">                   
                <div class="row" ng-if="$index % 3 == 0 ">
                    <i class="col col-33 {{icons[$index + n].icon}} custom-icon"></i>
                    <i class="col col-33 {{icons[$index + n + 1].icon}} custom-icon"></i>
                    <i class="col col-33 {{icons[$index + n + 2].icon}} custom-icon"></i>
                </div>
         </div>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.