[angularjs] ng-if와 ng-show / ng-hide의 차이점은 무엇입니까

ng-ifng-show/ 의 차이점을 이해하려고 ng-hide하지만 그들은 나에게 동일하게 보입니다.

둘 중 하나를 사용하기로 선택했을 때 명심해야 할 차이점이 있습니까?



답변

ngIf

ngIf지정 없애거나를 재생성 하는 식에 기초하여 DOM 트리의 일부. 할당 된 표현식 ngIf이 false 값 으로 평가되면 요소가 DOM에서 제거되고, 그렇지 않으면 요소의 복제본이 DOM에 다시 삽입됩니다.

<!-- when $scope.myValue is truthy (element is restored) -->
<div ng-if="1"></div>

<!-- when $scope.myValue is falsy (element is removed) -->
<div ng-if="0"></div>

ngIf해당 범위를 사용하여 요소를 제거 하면 요소가 복원 될 때 새 범위가 작성됩니다. 작성된 범위 ngIf는 프로토 타입 상속을 사용하여 상위 범위에서 상속됩니다.

부모 범위에 정의 된 JavaScript 프리미티브에 바인딩하는 ngModel데 사용되는 경우 ngIf자식 범위 내의 변수를 수정해도 부모 범위의 값에 영향을 미치지 않습니다 (예 :

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="data">
</div>        

이 상황을 해결하고 하위 범위 내에서 상위 범위의 모델을 업데이트하려면 객체를 사용하십시오.

<input type="text" ng-model="data.input">
<div ng-if="true">
    <input type="text" ng-model="data.input">
</div>

또는 $parent부모 범위 개체를 참조하는 변수 :

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="$parent.data">
</div>

ngShow

ngShow지시자 쇼 또는 가죽 받는 제공된 식에 기초하여 상기 지정된 HTML 엘리먼트 ngShow속성. 요소를 ng-hideCSS 클래스를 제거하거나 추가하여 요소가 표시되거나 숨겨집니다 . .ng-hideCSS 클래스는 AngularJS와의 사전 정의 (AN 사용하여 없음으로 표시 스타일을 설정되는 !important플래그).

<!-- when $scope.myValue is truthy (element is visible) -->
<div ng-show="1"></div>

<!-- when $scope.myValue is falsy (element is hidden) -->
<div ng-show="0" class="ng-hide"></div>

경우 ngShow에 표현들을 평가는 false다음 ng-hideCSS 클래스가 추가됩니다 class원인이되는 요소의 속성이 숨겨 될 수 있습니다. 때 true1, ng-hideCSS 클래스 요소를 일으키는 원인이되는 요소에서 제거되지 숨겨진 나타납니다.


답변

아마도 흥미로운 점은 둘 사이의 우선 순위의 차이 일 것입니다.

내가 알 수있는 한 ng-if 지시문은 모든 Angular 지시문 중 가장 높은 우선 순위 중 하나입니다. 즉, 우선 순위가 낮은 다른 모든 지시문보다 먼저 실행됩니다. 그것이 첫 번째로 실행된다는 사실은 내부 지시문이 처리 되기 전에 요소가 효과적으로 제거된다는 것을 의미 합니다. 또는 적어도 : 그것이 내가 만드는 것입니다.

현재 고객을 위해 구축하는 UI에서 이것을 관찰하고 사용했습니다. 전체 UI는 상당히 많이 포장되어 있으며 전체에 ng-show 및 ng-hide가 있습니다. 너무 자세하게 설명하지는 않지만 JSON 구성을 사용하여 관리 할 수있는 일반 구성 요소를 만들었으므로 템플릿 내에서 전환해야했습니다. ng-repeat가 존재하고 ng-repeat 내부에는 많은 ng-shows, ng-hides 및 ng-switches가있는 테이블이 표시됩니다. 그들은 목록에 적어도 50 번의 반복을 보여주고 싶었고 1500-2000 개의 지시어가 해결 될 것입니다. 코드를 확인하고 전면의 Java 백엔드 + 사용자 정의 JS가 데이터를 처리하는 데 약 150ms가 걸리고 Angular는 표시하기 전에 2-3 초 정도 씹습니다. 고객이 불만을 제기하지는 않았지만 겁이났습니다.

검색에서 ng-if 지시문을 우연히 발견했습니다. 이제이 UI를 구상 할 때 사용 가능한 ng-if가 없었 음을 지적하는 것이 가장 좋습니다. ng-show 및 ng-hide에는 부울을 반환하는 함수가 있기 때문에 모든 것을 ng-if로 쉽게 바꿀 수 있습니다. 그렇게함으로써, 모든 내부 지시문은 더 이상 평가되지 않는 것처럼 보였다. 즉, 평가되는 모든 지시문의 약 1/3로 돌아가서 UI가 최대 500ms-1 초의 로딩 시간으로 단축되었습니다. (정확한 초를 결정할 방법이 없습니다)

참고 사항 : 지시어가 평가되지 않는다는 사실은 아래에서 일어나는 일에 대한 교육받은 추측입니다.

따라서 내 의견으로는 : 페이지에 요소가 있어야하지만 요소를 확인하기 위해 숨겨져 있어야하지만 단순히 숨겨져 있다면 ng-show / ng-hide를 사용하십시오. 다른 모든 경우에는 ng-if를 사용하십시오.


답변

ng-if지시어는 페이지에서 콘텐츠를 제거하고 ng-show/ng-hide는 CSS를 사용 display숨기기 콘텐츠에 속성을.

이것은 당신이 사용하고자하는 경우에 유용 :first-child:last-child스타일로 의사 선택기.


답변

@EdSpencer가 정확합니다. 요소가 많고 ng-if를 사용하여 관련 요소 만 인스턴스화하면 리소스가 절약됩니다. @CodeHater는 요소를 매우 자주 제거하고 표시하려는 경우 요소를 제거하는 대신 숨기면 성능이 향상 될 수 있습니다.

ng-if의 주요 사용 사례는 내용이 불법 인 경우 요소를 깨끗하게 확인하고 제거 할 수 있다는 것입니다. 예를 들어 null 이미지 이름 변수를 참조 할 수 있으며 오류가 발생하지만 ng-if이고 null인지 확인하면 모두 좋습니다. ng-show를 수행하면 오류가 계속 발생합니다.


답변

ng-if 및 ng-show에 대해 유의해야 할 중요한 사항은 양식 컨트롤을 사용할 ng-if때 dom에서 요소를 완전히 제거하므로 사용하는 것이 좋습니다 .

이 차이는 입력 필드를 사용하여 입력 필드를 required="true"만든 다음 ng-show="false"숨기도록 설정 하면 사용자가 양식을 제출하려고 할 때 다음 오류가 발생 하기 때문에 중요 합니다.

An invalid form control with name='' is not focusable.

입력 필드 인 이유가 존재 required하지만 숨겨져 있기 때문에 Chrome에서 초점을 맞출 수 없습니다. 이 오류로 인해 스크립트 실행이 중단되므로 코드가 문자 그대로 중단 될 수 있습니다. 그러므로 조심 해주시길 바랍니다!


답변

@Gajus Kuizinas 및 @CodeHater가 정확합니다. 여기에 예제가 있습니다. ng-if로 작업하는 동안 할당 된 값이 false이면 전체 html 요소가 DOM에서 제거됩니다. 할당 된 값이 true이면 html 요소가 DOM에 표시됩니다. 범위는 상위 범위와 다릅니다. 그러나 ng-show의 경우 지정된 값을 기준으로 요소를 표시하고 숨길 수 있습니다. 그러나 항상 DOM에 남아 있습니다. 지정된 값에 따라 가시성 만 변경됩니다.

http://plnkr.co/edit/3G0V9ivUzzc8kpLb1OQn?p=preview

이 예제가 범위를 이해하는 데 도움이되기를 바랍니다. ng-show 및 ng-if에 잘못된 값을 제공하고 콘솔에서 DOM을 확인하십시오. 입력 상자에 값을 입력하고 차이를 관찰하십시오.

<!DOCTYPE html>

안녕하세요 플 런커!

<input type="text" ng-model="data">
<div ng-show="true">
    <br/>ng-show=true :: <br/><input type="text" ng-model="data">
</div>
<div ng-if="true">
    <br/>ng-if=true :: <br/><input type="text" ng-model="data">
</div>
{{data}}


답변

사실, ng-if지시어 는와 달리 ng-show자체 범위를 생성하여 흥미로운 실제 차이를 만듭니다.

angular.module('app', []).controller('ctrl', function($scope){
  $scope.delete = function(array, item){
    array.splice(array.indexOf(item), 1);
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app='app' ng-controller='ctrl'>
   <h4>ng-if:</h4>
   <ul ng-init='arr1 = [1,2,3]'>
      <li ng-repeat='x in arr1'>
        {{show}}
        <button ng-if='!show' ng-click='show=!show'>Delete {{show}}</button>
        <button ng-if='show' ng-click='delete(arr1, x)'>Yes {{show}}</button>
        <button ng-if='show' ng-click='show=!show'>No</button>
      </li>
   </ul>

   <h4>ng-show:</h4>
   <ul ng-init='arr2 = [1,2,3]'>
      <li ng-repeat='x in arr2'>
        {{show}}
        <button ng-show='!show' ng-click='show=!show'>Delete {{show}}</button>
        <button ng-show='show' ng-click='delete(arr2, x)'>Yes {{show}}</button>
        <button ng-show='show' ng-click='show=!show'>No</button>
      </li>
   </ul>

   <h4>ng-if with $parent:</h4>
    <ul ng-init='arr3 = [1,2,3]'>
      <li ng-repeat='item in arr3'>
        {{show}}
        <button ng-if='!show' ng-click='$parent.show=!$parent.show'>Delete {{$parent.show}}</button>
        <button ng-if='show' ng-click='delete(arr3, x)'>Yes {{$parent.show}}</button>
        <button ng-if='show' ng-click='$parent.show=!$parent.show'>No</button>
      </li>
   </ul>
</div>

첫 번째 목록 에서 내부 / 자체 범위의 on-click이벤트 show변수 가 변경되었지만 동일한 이름의 외부 범위 에서 다른 변수를보고 있으므로 솔루션이 작동하지 않습니다. 의 경우에서 우리는 하나 개가 작동 왜 변수, 즉. 첫 번째 시도를 해결 하려면를 통해 부모 / 외부 범위에서 참조해야합니다 .ng-ifng-showshowshow$parent.show