[angularjs] AngularJS에서 ng-repeat 범위가있는 지시 격리 범위

격리 범위가있는 지시문이 있습니다 (다른 위치에서 지시문을 재사용 할 수 있도록).이 지시문을에서 사용할 때 ng-repeat작동하지 않습니다.

이 주제에 대한 모든 문서와 Stack Overflow 답변을 읽었으며 문제를 이해했습니다. 나는 모든 일반적인 문제를 피했다고 믿습니다.

따라서 ng-repeat지시문에 의해 생성 된 범위 때문에 내 코드가 실패한다는 것을 이해합니다 . 내 자신의 지시문은 격리 범위를 만들고 부모 범위의 개체에 양방향 데이터 바인딩을 수행합니다. 내 지시문은이 바인딩 된 변수에 새 개체 값을 할당하며 내 지시문이없이 사용되면 완벽하게 작동합니다 ng-repeat(부모 변수가 올바르게 업데이트 됨). 그러나를 사용 ng-repeat하면 할당이 ng-repeat범위에 새 변수를 만들고 상위 변수에 변경 사항이 표시되지 않습니다. 이 모든 것은 내가 읽은 것을 바탕으로 예상 한 것입니다.

또한 주어진 요소에 여러 지시문이있을 때 하나의 범위 만 생성된다는 것도 읽었습니다. 그리고 priority각 지시문에 a 를 설정하여 지시문이 적용되는 순서를 정의 할 수 있습니다. 지시문은 우선 순위별로 정렬 된 다음 컴파일 기능이 호출됩니다 ( http://docs.angularjs.org/guide/directive 에서 우선 순위 단어 검색 ).

그래서 우선 순위를 사용하여 내 지시문이 먼저 실행되고 분리 범위를 생성하고 ng-repeat실행될 때 부모 범위에서 프로토 타입 적으로 상속되는 범위를 만드는 대신 분리 범위를 재사용 할 수 있기를 바랐습니다 . ng-repeat문서 상태 우선 순위 레벨에서 지시어 실행합니다 1000. 1더 높은 우선 순위 레벨인지 낮은 우선 순위 레벨 인지 는 명확하지 않습니다 . 1지시문에서 우선 순위를 사용했을 때 차이가 없어서 2000. 그러나 그것은 상황을 더 악화 undefined시킵니다. 내 양방향 바인딩이 되고 내 지시문은 아무것도 표시하지 않습니다.

내 문제를 보여주기 위해 바이올린을 만들었습니다 . priority내 지시에 설정을 주석으로 처리했습니다 . 이름 개체 목록과 이름 개체의 이름 name-row및 성 필드를 표시 하는 지시문이 있습니다. 표시된 이름을 클릭하면 selected메인 스코프에 변수 를 설정하고 싶습니다 . 이름 배열, selected변수는 name-row양방향 데이터 바인딩을 사용 하여 지시문에 전달됩니다 .

주 범위에서 함수를 호출하여이 작업을 수행하는 방법을 알고 있습니다. 또한 selected다른 개체 안에 있고 외부 개체에 바인딩하면 모든 것이 작동 한다는 것도 알고 있습니다. 그러나 현재로서는 이러한 솔루션에 관심이 없습니다.

대신 내가 가진 질문은 다음과 같습니다.

  • 어떻게 방지 할 ng-repeatprototypically의 상위 범위에서 상속하고, 대신 내 지시어의 분리-범위를 사용하는 것으로 범위를 만들 수?
  • 2000디렉티브의 우선 순위 레벨 이 작동하지 않는 이유는 무엇 입니까?
  • Batarang을 사용하여 사용중인 스코프 유형을 알 수 있습니까?



답변

좋아, 위의 많은 의견을 통해 혼란을 발견했습니다. 첫째, 몇 가지 설명이 있습니다.

  • ngRepeat는 선택한 격리 범위에 영향을주지 않습니다.
  • 당신의 지시자의 속성에서 사용하기 위해 ngRepeat에 전달 된 매개 변수는 않습니다 prototypically 상속 범위를 사용
  • 지시문이 작동하지 않는 이유는 격리 범위와 관련이 없습니다.

다음은 동일한 코드이지만 지시문이 제거 된 예입니다.

<li ng-repeat="name in names"
    ng-class="{ active: $index == selected }"
    ng-click="selected = $index">
    {{$index}}: {{name.first}} {{name.last}}
</li>

다음은 작동하지 않음을 보여주는 JSFiddle 입니다. 지시문에서와 똑같은 결과를 얻습니다.

왜 작동하지 않습니까? AngularJS의 범위는 프로토 타입 상속을 사용하기 때문입니다. selected부모 범위 의 값 은 기본 입니다. JavaScript에서 이것은 자식이 동일한 값을 설정하면 덮어 쓰게됨을 의미합니다. AngularJS 범위에는 황금률이 ​​있습니다. 모델 값 에는 항상 a .가 있어야 합니다. 즉, 그들은 결코 원시적이어서는 안됩니다. 자세한 내용은 이 SO 답변 을 참조하십시오.


다음은 스코프의 초기 모습입니다.

여기에 이미지 설명 입력

첫 번째 항목을 클릭하면 이제 범위가 다음과 같이 표시됩니다.

여기에 이미지 설명 입력

selectedngRepeat 범위에 새 속성이 생성되었습니다. 컨트롤러 범위 003은 변경되지 않았습니다.

두 번째 항목을 클릭하면 어떤 일이 발생하는지 짐작할 수 있습니다.

여기에 이미지 설명 입력


따라서 귀하의 문제는 실제로 ngRepeat로 인한 것이 아니라 AngularJS의 황금률을 위반하여 발생합니다. 이를 수정하는 방법은 단순히 객체 속성을 사용하는 것입니다.

$scope.state = { selected: undefined };
<li ng-repeat="name in names"
    ng-class="{ active: $index == state.selected }"
    ng-click="state.selected = $index">
    {{$index}}: {{name.first}} {{name.last}}
</li>

다음은 이 작업을 보여주는 두 번째 JSFiddle 입니다.

처음에 범위는 다음과 같습니다.

여기에 이미지 설명 입력

첫 번째 항목을 클릭 한 후 :

여기에 이미지 설명 입력

여기서 컨트롤러 범위는 원하는대로 영향을받습니다.

또한 이것이 격리 범위를 사용하여 지시문과 함께 작동한다는 것을 증명하기 위해 (다시 말하지만 이것은 문제와 관련이 없기 때문에) 여기에 JSFiddle 도 있습니다.보기는 객체를 반영해야합니다. 필요한 유일한 변경 사항은 primitive 대신 객체 를 사용하는 것입니다 .

초기 범위 :

여기에 이미지 설명 입력

첫 번째 항목을 클릭 한 후 범위 :

여기에 이미지 설명 입력

결론 : 다시 한 번, 귀하의 문제는 격리 범위와 관련된 것이 아니며 ngRepeat의 작동 방식과 관련이 없습니다. 문제는 바로이 문제를 일으키는 것으로 알려진 규칙을 위반하고 있다는 것입니다. AngularJS의 모델은 항상 ..


답변

질문에 직접 답하지 않고 대신 다음 바이올린을 살펴보십시오.

http://jsfiddle.net/dVPLM/

요점은 Angular의 기존 동작에 맞서 싸우고 변경하는 대신, ng-repeat재정의를 시도하는 대신 작업하도록 지시문을 구성 할 수 있다는 것입니다.

템플릿에서 :

    <name-row 
        in-names-list="names"
        io-selected="selected">
    </name-row>

당신의 지시에서 :

    template:
'        <ul>' +      
'            <li ng-repeat="name in inNamesList" ng-class="activeClass($index)" >' +
'                <a ng-click="setSelected($index)">' +
'                    {{$index}} - {{name.first}} {{name.last}}' +
'                </a>' +
'            </li>' +
'        </ul>'

귀하의 질문에 대한 답변 :

  • ng-repeat 스코프를 만들 것입니다. 정말로 이것을 변경하려고해서는 안됩니다.
  • 지시문의 우선 순위는 실행 순서가 아닙니다. 참조 : AngularJS : HTML 컴파일러는 컴파일 순서를 어떻게 정렬합니까?
  • Batarang에서 성능 탭을 확인하면 각 범위에 바인딩 된 표현식을 볼 수 있으며 이것이 예상과 일치하는지 확인할 수 있습니다.


답변