Angularjs ng-model tidak berfungsi di dalam ng-if

206

Ini biola yang menunjukkan masalahnya. http://jsfiddle.net/Erk4V/1/

Tampaknya jika saya memiliki model ng di dalam sebuah ng-jika, model tersebut tidak berfungsi seperti yang diharapkan.

Saya bertanya-tanya apakah ini bug atau jika saya salah memahami penggunaan yang tepat.

<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>
Justin Carlson
sumber
6
Untuk pemecahannya Anda dapat menggunakan ng-show = "CONDITION" alih-alih ng-if. Itu harus bekerja.
Hari Das
Saya kira ini bukan masalah lagi karena sekarang orang bisa menggunakannya controllerAs?
jamiebarrow
Saya memiliki masalah yang sama ketika menggunakan arahan dengan implisit scope:falsedan saya menambahkanng-if elemen di sekitar arahan - cakupan awalnya terikat, tetapi mereka menjadi terpisah setelah pengamat memperbarui salah satu nilai ruang lingkup ...
Aprillion

Jawaban:

223

Itu ng-if direktif, seperti arahan lain menciptakan lingkup anak. Lihat skrip di bawah ini (atau jsfiddle ini )

<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>

Jadi, kotak centang Anda mengubah bagian testbdalam lingkup anak, tetapi bukan lingkup induk luar.

Perhatikan, bahwa jika Anda ingin memodifikasi data dalam lingkup induk, Anda harus memodifikasi properti internal objek seperti di div terakhir yang saya tambahkan.

Jon7
sumber
1
Bagaimana saya mengakses ruang lingkup ng-if dari dalam fungsi pengendali utama? Agak frustasi. Apa alasannya?
Justin Carlson
Nevermind, @sza baru saja menjawab pertanyaan itu. Saya akan menandai jawaban ini sebagai benar, karena itu menjelaskan alasan pasti saya mengalami masalah.
Justin Carlson
21
Ini adalah salah satu alasan mengapa cukup umum untuk menggunakan objek yang berisi lingkup Anda, daripada memodifikasi properti lingkup secara langsung, seperti yang ditunjukkan dalam contoh: $scope.obj = {...}dan ng-model="obj.someProperty"mengatasi batasan ini.
wulftone
204

Kamu bisa memakai $parent untuk merujuk ke model yang ditentukan dalam lingkup induk seperti ini

<input type="checkbox" ng-model="$parent.testb" />
zs2020
sumber
16
maka saya miliki ng-model="$parent.$parent.fookarena saya sudah berada dalam ruang lingkup dengan ng-repeat- apakah ini benar-benar cara terbaik?
chovy
4
ini benar-benar membingungkan. mengapa demikian? dan mengapa ng-hide tidak memiliki cakupan sendiri?
Dominik Goltermann
5
Re @Gaul: mungkin karena ng-hide / ng-show beroperasi pada DOM saat ini dan hanya menambah / menghapus kelas CSS, sementara ng-if / ng-switch / ng-ulangi semua kotoran dengan DOM dan melacak status tambahan . Tampaknya masuk akal.
trisweb
4
Masuk akal bukan kata yang saya gunakan.
Jonathan Dumaine
3
Tambahkan objek ke ruang lingkup asli, dan ubah properti objek itu. misalnya ng-model = "myObject.property". Ini akan menghindari semua scope / $ parent inanity. Google "aturan titik sudut" untuk info lebih lanjut.
Asmor
50

Anda dapat menggunakan arahan ngHide (atau ngShow) . Itu tidak membuat ruang lingkup anak seperti halnya jika tidak.

<div ng-hide="testa">
Vasiliy Kevroletin
sumber
3
Mengapa ngIfkemudian menciptakan ruang lingkup anak? Sepertinya sangat aneh bagi saya.
gratis semua
5
Perhatikan komentar jawaban zsong. ng-hidetidak mengubah struktur html. Itu hanya mengubah gaya css. ng-iflebih kompleks: menghapus dan menyisipkan bagian html tergantung kondisi. Ini menciptakan ruang lingkup anak untuk menyimpan keadaan (setidaknya itu harus menyimpan bagian html tersembunyi).
Vasiliy Kevroletin
Yup, Bekerja untukku
Basit
7

Kami memiliki ini dalam banyak kasus lain, apa yang kami putuskan secara internal adalah untuk selalu memiliki pembungkus untuk pengontrol / arahan sehingga kita tidak perlu memikirkannya. Inilah Anda contoh dengan pembungkus kami.

<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>

Semoga ini bisa membantu, Yishay

Yishay Haspel
sumber
3

Ya, arahan ng-hide (atau ng-show) tidak akan membuat cakupan anak.

Inilah latihan saya:

<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/

Xiayan Y
sumber
0

Anda dapat melakukannya seperti ini dan fungsi mod Anda akan bekerja dengan sempurna beri tahu saya jika Anda ingin pena kode

  <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>
Xvega
sumber