ng-repeat 내의 명령어와 스코프 '@'의 불가사의한 힘 사용
현용 코드로 질문을 표시하는 경우는, http://jsbin.com/ayigub/2/edit 를 참조해 주세요.
간단한 서사시를 쓰는 것과 거의 같은 방법을 생각해 봅시다.
app.directive("drinkShortcut", function() {
return {
scope: { flavor: '@'},
template: '<div>{{flavor}}</div>'
};
});
app.directive("drinkLonghand", function() {
return {
scope: {},
template: '<div>{{flavor}}</div>',
link: function(scope, element, attrs) {
scope.flavor = attrs.flavor;
}
};
});
2개의 디렉티브를 단독으로 사용하는 경우, 2개의 디렉티브는 동일하게 동작합니다.
<!-- This works -->
<div drink-shortcut flavor="blueberry"></div>
<hr/>
<!-- This works -->
<div drink-longhand flavor="strawberry"></div>
<hr/>
단, ng-repeat 내에서 사용하는 경우 숏컷버전만 동작합니다
<!-- Using the shortcut inside a repeat also works -->
<div ng-repeat="flav in ['cherry', 'grape']">
<div drink-shortcut flavor="{{flav}}"></div>
</div>
<hr/>
<!-- HOWEVER: using the longhand inside a repeat DOESN'T WORK -->
<div ng-repeat="flav in ['cherry', 'grape']">
<div drink-longhand flavor="{{flav}}"></div>
</div>
질문은 다음과 같습니다.
- ng-repeat에서는 왜 landhand 버전이 동작하지 않는 거죠?
- 어떻게 ng-repeat 안에서 longhand 버전을 작동시킬 수 있습니까?
인drinkLonghand
, 코드를 사용합니다.
scope.flavor = attrs.flavor;
링크 단계에서 보간된 속성은 아직 평가되지 않았기 때문에 값은 다음과 같습니다.undefined
(외부에서 근무하고 있습니다.ng-repeat
왜냐하면 이러한 경우 문자열 보간법을 사용하지 않고 일반적인 문자열(예: "brackberry")을 통과하기 때문입니다.이는 Directives 개발자 가이드와 함께 다음 방법에 설명되어 있습니다.Attributes
API 문서에는 없는 명령어입니다.$observe
:
사용하다
$observe
보간(예: 보간)을 포함하는 속성의 값 변화를 관찰합니다.src="{{bar}}"
이것은 매우 효율적일 뿐만 아니라 실제 값을 쉽게 얻을 수 있는 유일한 방법입니다. 왜냐하면 링크 단계에서는 보간법이 아직 평가되지 않았기 때문입니다.따라서 현시점에서는 값이 다음과 같이 설정됩니다.undefined
.
이 문제를 해결하려면drinkLonghand
디렉티브는 다음과 같습니다.
app.directive("drinkLonghand", function() {
return {
template: '<div>{{flavor}}</div>',
link: function(scope, element, attrs) {
attrs.$observe('flavor', function(flavor) {
scope.flavor = flavor;
});
}
};
});
단, 이 문제의 문제는 격리 스코프를 사용하지 않는다는 것입니다.따라서 회선은
scope.flavor = flavor;
라고 하는 이름의 스코프상의 기존 변수를 덮어쓸 가능성이 있습니다.flavor
공백 격리 스코프를 추가하는 것도 기능하지 않습니다.이는 Angular가 명령어 스코프를 기반으로 스트링을 보간하려고 하기 때문입니다.이것에 대해서는, 라고 하는 어트리뷰트가 없습니다.flav
. (이를 테스트하려면scope.flav = 'test';
할 필요 이상으로attrs.$observe
.)
물론 다음과 같은 격리된 범위 정의를 사용하여 이 문제를 해결할 수 있습니다.
scope: { flav: '@flavor' }
또는 비표준 자 스코프를 생성하여
scope: true
또는 에 의존하지 않음으로써template
와 함께{{flavor}}
대신 직접 DOM 조작을 합니다.
attrs.$observe('flavor', function(flavor) {
element.text(flavor);
});
그러나 그것은 연습의 목적에 어긋난다(예를 들어, 단순히 사용법을 사용하는 것이 더 쉬울 것이다).drinkShortcut
메서드).그래서 이 지시가 제대로 작동하도록 하기 위해, 우리가 직접 지령서에 대한 보간 작업을 할 수 있는 서비스를 시작할 겁니다.$parent
표시:
app.directive("drinkLonghand", function($interpolate) {
return {
scope: {},
template: '<div>{{flavor}}</div>',
link: function(scope, element, attrs) {
// element.attr('flavor') == '{{flav}}'
// `flav` is defined on `scope.$parent` from the ng-repeat
var fn = $interpolate(element.attr('flavor'));
scope.flavor = fn(scope.$parent);
}
};
});
물론 이것은 초기값에만 유효합니다.scope.$parent.flav
값을 변경할 수 있다면 보간 함수의 결과를 사용하고 재평가해야 합니다.fn
알 수 이 안 $watch
을 참조해 주십시오.)scope: { flavor: '@' }
이 모든 복잡성을 관리할 필요가 없는 좋은 지름길입니다.
[갱신]
코멘트에서 질문에 답하려면:
지름길은 어떻게 이면에서 이 문제를 해결하고 있을까요?고객님과 마찬가지로 $interpolate 서비스를 사용하고 있습니까, 아니면 다른 서비스를 사용하고 있습니까?
나는 이것에 대해 확신이 없어서 출처를 찾아봤어요.는 the음음음음 i i음음 i 。compile.js
:
forEach(newIsolateScopeDirective.scope, function(definiton, scopeName) {
var match = definiton.match(LOCAL_REGEXP) || [],
attrName = match[2]|| scopeName,
mode = match[1], // @, =, or &
lastValue,
parentGet, parentSet;
switch (mode) {
case '@': {
attrs.$observe(attrName, function(value) {
scope[scopeName] = value;
});
attrs.$$observers[attrName].$$scope = parentScope;
break;
}
래서런 so so so so so so so so so so so so?attrs.$observe
로 하는 것을 할 수 있습니다(, Atribute의 위).break
수 , 「」, 「2」가 있는 것은 $$
API에 될 수 (Prefix Angular API를 수 ).@
를 선택합니다.
언급URL : https://stackoverflow.com/questions/16502559/using-a-directive-inside-an-ng-repeat-and-a-mysterious-power-of-scope
'programing' 카테고리의 다른 글
Express 핸들바와 각도 JS 사용 (0) | 2023.02.15 |
---|---|
SpringJunit4에서 테스트 고유의 ContextConfiguration과 함께 @ComponentScan을 사용하는 방법Test Runner? (0) | 2023.02.15 |
워드프레스 next_post_link/previous_post_link가 동일한 범주에 속하지 않습니다. (0) | 2023.02.15 |
React에서 페이지 번호부여를 구현하는 방법 (0) | 2023.02.15 |
ESLint 기본 내보내기 Import/prefer-default-export 선호 (0) | 2023.02.15 |