Angularjs ng-model không hoạt động bên trong ng-if


206

Đây là fiddle cho thấy vấn đề. http://jsfiddle.net/Erk4V/1/

Nó xuất hiện nếu tôi có một mô hình ng bên trong một ng-if, mô hình không hoạt động như mong đợi.

Tôi tự hỏi nếu đây là một lỗi hoặc nếu tôi hiểu sai cách sử dụng đúng.

<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
Đối với cách giải quyết, bạn có thể sử dụng ng-show = "ĐIỀU KIỆN" thay vì ng-if. Nó nên hoạt động.
Hari Das

Tôi cho rằng đây không còn là vấn đề mà người ta có thể sử dụng controllerAs?
jamiebarrow

Tôi đã cùng một vấn đề khi sử dụng một chỉ thị với ngầm scope:falsevà tôi đã thêm ng-ifyếu tố xung quanh chỉ thị - phạm vi bị ràng buộc ban đầu, nhưng họ đã trở thành tách sau một watcher cập nhật một trong những giá trị phạm vi ...
Aprillion

Câu trả lời:


223

Lệnh ng-ifnày, giống như các chỉ thị khác tạo ra một phạm vi con. Xem kịch bản dưới đây (hoặc jsfiddle này )

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

Vì vậy, hộp kiểm của bạn thay đổi testbbên trong phạm vi con, nhưng không thay đổi phạm vi cha mẹ bên ngoài.

Lưu ý rằng nếu bạn muốn sửa đổi dữ liệu trong phạm vi cha, bạn sẽ cần sửa đổi các thuộc tính bên trong của một đối tượng như trong div cuối cùng mà tôi đã thêm.


1
Làm thế nào tôi có thể truy cập phạm vi ng-if từ bên trong chức năng của bộ điều khiển chính? Một chút bực bội. Lý do cho điều này là gì?
Justin Carlson

Nevermind, @sza chỉ trả lời ^ câu hỏi đó. Tôi sẽ đánh dấu câu trả lời này là chính xác, vì nó giải thích chính xác lý do tôi gặp vấn đề.
Justin Carlson

21
Đây là một lý do khá phổ biến để sử dụng một đối tượng chứa trên phạm vi của bạn, thay vì trực tiếp sửa đổi các thuộc tính phạm vi, như được chỉ ra trong ví dụ: $scope.obj = {...}ng-model="obj.someProperty"khắc phục giới hạn này.
wulftone

204

Bạn có thể sử dụng $parentđể tham khảo mô hình được xác định trong phạm vi cha như thế này

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

16
sau đó tôi có ng-model="$parent.$parent.foobởi vì tôi đã ở trong một phạm vi với một ng-repeat- đây có thực sự là cách tốt nhất?
chovy

4
Điều này thực sự khó hiểu. tại sao vậy? và tại sao ng-hide không có phạm vi riêng?
Dominik Goltermann

5
Re @Gaul: có lẽ vì ng-hide / ng-show hoạt động trên DOM hiện tại và chỉ cần thêm / xóa một lớp CSS, trong khi ng-if / ng-switch / ng-lặp lại tất cả muck với DOM và theo dõi trạng thái bổ sung . Có vẻ hợp lý.
trisweb

4
Sensible không phải là từ tôi sử dụng.
Jonathan Dumaine

3
Thêm một đối tượng vào phạm vi ban đầu và thay đổi thuộc tính của đối tượng đó. ví dụ: ng-model = "myObject.property". Điều này sẽ vượt qua tất cả phạm vi / $ cha mẹ vô tri. Google "quy tắc chấm góc" để biết thêm thông tin.
Asmor

50

Bạn có thể sử dụng chỉ thị ngHide (hoặc ngShow) . Nó không tạo phạm vi con như ng If.

<div ng-hide="testa">

3
Tại sao ngIfsau đó tạo ra một phạm vi con? Có vẻ rất lạ đối với tôi.
freeall

5
Hãy chú ý đến ý kiến ​​của câu trả lời zsong. ng-hidekhông thay đổi cấu trúc html. Nó chỉ đơn giản là thay đổi phong cách css. ng-ifphức tạp hơn: nó loại bỏ và chèn các phần html tùy theo điều kiện. Nó tạo phạm vi con để lưu trữ trạng thái (ít nhất là nên lưu trữ phần html ẩn).
Vasiliy Kevroletin

Yup, làm việc cho tôi
Basit

7

Chúng tôi đã có điều này trong nhiều trường hợp khác, điều chúng tôi quyết định trong nội bộ là luôn có một trình bao bọc cho bộ điều khiển / chỉ thị để chúng tôi không cần phải suy nghĩ về nó. Dưới đây là ví dụ của bạn với trình bao bọc của chúng tôi.

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

Hy vọng điều này sẽ giúp, Yishay


3

Có, chỉ thị ng-hide (hoặc ng-show) sẽ không tạo phạm vi con.

Đây là thực hành của tôi:

<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

Bạn có thể làm như thế này và chức năng mod của bạn sẽ hoạt động hoàn hảo cho tôi biết nếu bạn muốn một cây bút mã

  <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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.