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:falseng-if요소를 추가 했습니다. 범위는 처음에 바인딩되었지만 감시자가 범위 값 중 하나를 업데이트 한 후 분리되었습니다.
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
이 하나는 예 뾰족한 아웃으로 대신 직접 범위 속성을 수정하는 것보다, 당신의 범위에 포함 된 객체를 사용하는 것이 매우 일반적입니다 이유 $scope.obj = {...}ng-model="obj.someProperty"극복이 제한.
wulftone

204

$parent다음과 같이 상위 범위에 정의 된 모델을 참조하는 데 사용할 수 있습니다

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

16
그런 다음 ng-model="$parent.$parent.foo이미 범위 안에 있기 때문에 ng-repeat이것이 가장 좋은 방법입니까?
chovy

4
정말 혼란 스럽습니다. 왜 그런 겁니까? 왜 ng-hide에 자체 범위가 없습니까?
Dominik Goltermann

5
Re @Gaul : 아마도 ng-hide / ng-show가 현재 DOM에서 작동하고 CSS 클래스를 추가 / 제거하기 때문에 ng-if / ng-switch / ng-rep는 DOM으로 모든 퍽을 제거하고 추가 상태를 추적하기 때문에 . 현명 해 보인다.
trisweb

4
현명한 단어는 내가 사용하는 단어 가 아닙니다 .
Jonathan Dumaine

3
원래 범위에 개체를 추가하고 해당 개체의 속성을 변경하십시오. 예 : ng-model = "myObject.property" 이것은 모든 스코프 / $ parent 무죄를 회피 할 것입니다. 자세한 내용은 Google "각도 규칙"을 참조하십시오.
Asmor

50

ngHide (또는 ngShow) 지시문을 사용할 수 있습니다 . ngIf처럼 자식 범위를 만들지 않습니다.

<div ng-hide="testa">

3
ngIf그러면 왜 자식 범위를 생성합니까? 나에게는 매우 이상해 보인다.
freeall

5
zsong answer의 의견에주의하십시오. ng-hideHTML 구조를 변경하지 않습니다. 단순히 CSS 스타일을 변경합니다. ng-if더 복잡합니다 : 조건에 따라 HTML 부분을 제거하고 삽입합니다. 상태를 저장할 하위 범위를 만듭니다 (적어도 숨겨진 HTML 부분을 저장해야 함).
Vasiliy Kevroletin 2016 년

아, 그래, 나를 위해 일
바싯 대변인

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.