IT TIP

Angularjs가 transcluded 및 격리 범위 및 바인딩에 대해 혼란 스러움

itqueen 2021. 1. 5. 20:48
반응형

Angularjs가 transcluded 및 격리 범위 및 바인딩에 대해 혼란 스러움


제한된 범위를 가진 지시문과 관련하여 모델의 범위와 바인딩을 이해하는 데 어려움을 겪고 있습니다.

지시문에서 범위를 제한한다는 것은 controller. $ scope와 directive.scope가 더 이상 동일하지 않다는 것을 의미합니다. 그러나 디렉티브 템플릿 또는 html 내에서 모델을 배치하는 것이 데이터 바인딩에 어떤 영향을 미치는지에 대해 혼란 스럽습니다. 나는 내가 매우 근본적인 것을 놓치고 있다고 생각하며 계속 나아 가기 위해서는 이것을 이해할 필요가 있습니다.

다음 코드를 가져옵니다 (여기에서 바이올린 : http://jsfiddle.net/2ams6/ ).

자바 스크립트

var app = angular.module('app',[]);
app.controller('Ctrl',function($scope){
});
app.directive('testel', function(){
    return {
        restrict: 'E',
        scope: {
            title: '@'
        },
        transclude: true,
        template:   '<div ng-transclude>'+
                    '<h3>Template title: {{title}}</h3>' +
                    '<h3>Template data.title:{{data.title}}</h3>' +
                    '</div>'
    }    
}); 

HTML

<div ng-app='app'>
    <div ng-controller="Ctrl">
        <input ng-model="data.title">
        <testel title="{{data.title}}">
            <h3>Transclude title:{{title}}</span></h3>
            <h3>Transclude data.title:{{data.title}}</h3>
        </testel>
    </div>
</div>

모델 {{title}}은 템플릿 내 에서만 업데이트 됩니다 {{data.title}}. {{title}}초월이나 {{data.title}}템플릿에 있지 않습니까?

입력을 다음과 같이 transclusion 내로 이동합니다 (여기에서 바이올린 : http://jsfiddle.net/eV8q8/1/ ).

<div ng-controller="Ctrl">
    <testel title="{{data.title}}">
        <input ng-model="data.title">
         <h3>Transclude title: <span style="color:red">{{title}}</span></h3>

         <h3>Transclude data.title: <span style="color:red">{{data.title}}</span></h3>

    </testel>
</div>

이제 transclude 만 {{data:title}}업데이트 됨을 의미합니다 . 템플릿 {{title}}또는 또는 {{data.title}}transclude가 아닌 이유는 무엇 {{title}}입니까?

마지막으로 입력을 템플릿 내로 이동합니다 (여기에서 바이올린 : http://jsfiddle.net/4ngmf/2/ ).

template: '<div ng-transclude>' +
            '<input ng-model="data.title" />' +
            '<h3>Template title: {{title}}</h3>' +
            '<h3>Template data.title: {{data.title}}</h3>' +
            '</div>'

이제는 템플릿 만 {{data.title}}업데이트 됨을 의미합니다 . 다시 말하지만, 다른 3 개의 바인딩은 어떻습니까?

나는 명백한 무언가가 나를 쳐다보고 있고 그것을 놓치고 있기를 바랍니다. 이걸 가져 오면 맥주를 사주거나 포인트를 줄 게요. 감사합니다.


바이올린은 세 가지 범위를 만듭니다.

  1. 컨트롤러와 관련된 범위로 Ctrl인해ng-controller
  2. 지시문에 포함 된 범위는 transclude: true
  3. 지시문 격리 범위 때문에 scope: { ... }

fiddle1에서 텍스트 상자에 입력하기 전에 다음과 같은 내용이 있습니다.

여기에 이미지 설명 입력

범위 003은 컨트롤러와 관련된 범위입니다. 아직 텍스트 상자에 입력하지 않았으므로 data속성 이 없습니다 . 격리 범위 004에서 title속성이 생성되었지만 비어 있음을 알 수 있습니다. 부모 범위에 data.title아직 속성 이 없기 때문에 비어 있습니다.

my title텍스트 상자에 입력 하면 이제 다음과 같이됩니다.

여기에 이미지 설명 입력

컨트롤러 범위 003 이제 새가 data이있는, (이 노란 색깔의 이유입니다) 객체 속성을 title현재로 설정 속성을 my title. 격리 범위 속성 title은 보간 된 값에 단방향 데이터 바인딩 data.title되므로 값도 가져옵니다 my title(값이 변경 되었기 때문에 노란색으로 표시됨).

transcluded 범위는 컨트롤러 범위에서 프로토 타입으로 상속되므로 transcluded HTML 내에서 angular는 프로토 타입 체인 $scope.data.title을 따라 상위 범위에서 찾을 수 있습니다 (하지만 $scope.title거기에 존재하지 않음).

격리 범위는 자체 속성에만 액세스 할 수 있으므로 property 만 있습니다 title.

fiddle2에서 입력하기 전에 fiddle1과 동일한 그림이 있습니다.

입력 후 my title:

여기에 이미지 설명 입력

data.titletranscluded 범위 에서 새 속성이 표시된 위치를 확인합니다. 격리 범위는 여전히 data.title컨트롤러 범위에서 찾고 있지만 이번에는 존재하지 않으므로 title속성 값이 비어 있습니다.

fiddle3에서 입력하기 전에 fiddle1과 동일한 그림이 있습니다.

입력 후 my title:

여기에 이미지 설명 입력

data.title격리 범위 에서 새 속성 이 표시된 위치를 확인합니다 . 다른 범위는 격리 범위에 액세스 할 수 없으므로 문자열 my title이 다른 곳에 표시되지 않습니다.


Angular v1.2 업데이트 :

변경 사항 eed299a Angular는 이제 transclusion 지점을 지워서 transcluding 하기 전에 다음 Template title: ...Template data.title: ...같이 템플릿을 수정하지 않는 한 부품이 표시되지 않습니다 ng-transclude.

'<h3>Template title: <span style="color:red">{{title}}</span></h3>' +
'<h3>Template data.title: <span style="color:red">{{data.title}}</span></h3>' +
'<div ng-transclude></div>'

In the update below for Angular v1.3, this template change was made.


Update for Angular v1.3+:

Since Angular v1.3, the transcluded scope is now a child of the directive's isolate scope, rather than a child of the controller scope. So in fiddle1, before we type anything:

여기에 이미지 설명 입력

The pictures in this update are drawn with the Peri$scope tool, so the pictures are a bit different. The @ indicates we have an isolate scope property that uses the @ syntax, and the pink background means that the tool was unable to find an ancestor reference for the mapping (which is true, since we didn't type anything in to the textbox yet).

After typing my title into the textbox, we now have:

여기에 이미지 설명 입력

Isolate properties that use @ binding will always show the interpolated string result in the isolate scope after the @ symbol. Peri$scope was also able to find this exact string value in an ancestor scope, so it also shows a reference to that property.

In fiddle 2, before typing we have the same picture as in fiddle1.

After typing my title:

여기에 이미지 설명 입력

Notice where the new data.title property showed up -- on the transcluded scope. The isolate scope is still looking for data.title on the controller scope, but its not there this time, so its title property value remains empty.

In fiddle3, before typing we have the same picture as in fiddle1.

After typing my title:

여기에 이미지 설명 입력

Notice where the new data.title property showed up -- on the isolate scope. Even though the transcluded scope has access to the isolate scope via the $parent relationship, it won't look there for title or data.title -- it will only look in the controller scope (i.e., it will follow the prototypal inheritance), and the controller scope doesn't have these properties defined.


After reading through all the answers presented, including Mark's fantastic schematics, this is my understanding of scope and it's inheritance per my question. I would appreciate comments on where this diagram falls down, in order I can update appropriately. I hope it simply provides a different view to what Mark has presented:

범위 상속


Well asked, btw! Hope my answer is as eloquent..

The answer has to do with how transcluded elements get their scope.

To summarize, you've got two scopes:

  1. The controller's scope, which has $scope.data.title. (Implicitly added by your input element)
  2. The directive's scope, which has $scope.title.

When you change the controller's $scope.data.title, directive's $scope.title also changes.

You've also got two sections of HTML, the transcluded and the template. What's happening is that the transcluded HTML is in the controller's scope, and the template HTML is in the directive's scope. So the transcluded HTML doesn't know anything about title, and the template scope doesn't know anything about data.title

이것은 실제로 Transclusion이 의도 한 것 입니다. 지시어의 자식 요소가 부모 범위 ( 이 경우 컨트롤러의 범위)를 유지할 수 있도록합니다 . 설계 상, transcluded 요소는 지시문에 있음을 알지 못하므로 지시문 범위에 액세스 할 수 없습니다.

반면에 디렉티브 템플릿은 디렉티브 범위에만 액세스 할 수 있습니다.

이름을 좀 더 명확하게하기 위해 코드를 약간 변경했습니다 (하지만 동일한 기능).

http://jsfiddle.net/yWWVs/2/

참조 URL : https://stackoverflow.com/questions/16653004/confused-about-angularjs-transcluded-and-isolate-scopes-bindings

반응형