transcluded 범위가있는 지시문에서 양방향 바인딩이 작동하지 않음
model에 바인딩 된 컨트롤러에 텍스트 상자가 있습니다 name
. 컨트롤러 내부에 지시문이 있고 동일한 모델에 바인딩 된 지시문 내부에 또 다른 텍스트 상자가 있습니다 name
.
<div class="border" ng-controller="editCtrl">
Controller: editCtrl <br/>
<input type="text" ng-model="name" />
<br/>
<tabs>
Directive: tabs <br/>
<input type="text" ng-model="name"/>
</tabs>
</div>
mod.directive('tabs', function() {
return {
restrict: 'E',
transclude: true,
template:
'<div class="border" ng-transclude></div>',
};
});
외부 텍스트 상자에 무언가를 입력하면 내부 텍스트 상자에 반영되지만 내부 텍스트 상자에 무언가를 입력하면 작동이 중지됩니다. 즉 두 텍스트 상자가 더 이상 동일한 값을 반영하지 않습니다.
http://jsfiddle.net/uzairfarooq/MNBLd/ 에서 예를 참조하십시오.
또한 양방향 바인딩 attr ( scope: {name: '='}
)을 사용해 보았지만 구문 오류 scope: {name: '@'}
가 발생하고 동일한 효과가 있습니다.
어떤 도움이라도 대단히 감사하겠습니다.
받아 들여진 답변 외에도이 기사는 아동 scpoes의 프로토 타입 상속을 이해하는 데 실제로 도움 이 되었습니다. 스코프에 문제가있는 모든 사람이 자세히 읽어 볼 것을 강력히 권장합니다.
지시문이 transclude: true
있는 지시문은 새 (제외 된) 하위 범위를 생성합니다. 이 새 범위는 프로토 타입 적으로 상위 범위에서 상속됩니다. 귀하의 경우 부모 범위는 editCtrl 컨트롤러와 관련된 범위입니다.
자식 범위 (예 : ng-model)에서 양방향 데이터 바인딩을 사용하여 원시 값 (예 :)을 보유하는 부모 범위 속성에 바인딩 name
하면 항상 문제가 발생합니다. 예상대로 작동하지 않는다고 말해야합니다. . 자식에서 범위 속성이 변경되면 (예 : 두 번째 텍스트 상자에 입력) 자식은 동일한 이름의 부모 범위 속성을 숨기거나 숨기는 새 범위 속성을 만듭니다. 부모 속성에 기본 값이있는 경우 해당 값은 자식 속성이 생성 될 때 (본질적으로) 자식 속성에 복사됩니다 . 자식 범위 (예 : 두 번째 텍스트 상자)의 향후 변경 사항은 자식 속성에만 영향을줍니다.
두 번째 텍스트 상자에 입력하기 전에 (즉, 자식에서 속성이 변경되기 전) 자식 / 제외 된 범위는 name
프로토 타입 상속을 통해 부모 범위에서 속성을 찾습니다 (아래 그림의 점선). 이것이 두 텍스트 상자가 처음에 동기화 된 상태로 유지되는 이유입니다. 아래에서 첫 번째 텍스트 상자에 "Mark"를 입력하면 범위는 다음과 같습니다.
두 범위를 검사 할 수 있는 바이올린을 만들었습니다 . 두 번째 텍스트 상자에 입력하기 전에 두 번째 텍스트 상자 옆에있는 "범위 표시"링크를 클릭하십시오. 이렇게하면 transcluded 자식 범위를 볼 수 있습니다. name
이 시점에서 속성 이 없다는 것을 알 수 있습니다. 콘솔을 지우고 두 번째 텍스트 상자에 입력 한 다음 링크를 다시 클릭하십시오. 이제 자식 범위에 name
속성이 있고 초기 값이 부모 속성의 값 ( "Mark")임을 알 수 있습니다. 두 번째 텍스트 상자에 "likes Angular"를 입력 한 경우 범위는 다음과 같습니다.
두 가지 솔루션이 있습니다.
- @ pgreen2가 제안하는대로 수행하십시오 (이는 "모범 사례"솔루션입니다). 기본 요소 대신 객체를 사용하십시오. 개체가 사용되는 경우 자식 / 제외 된 범위는 새 속성을 가져 오지 않습니다. 여기서는 프로토 타입 상속 만이 작용합니다. 아래 그림에서 editCtrl의 $ scope에 다음 개체가 정의되어 있다고 가정합니다
$scope.myObject = { name: "Mark", anotherProp: ... }
.
- 하위 범위에서 $ parent를 사용합니다 (이는 취약한 솔루션이며 HTML 구조에 대한 가정을하기 때문에 권장되지 않습니다) :
ng-model="$parent.name"
<tabs> 요소 내에있는 <input> 내부에서 사용 합니다. 위의 첫 번째 그림은 이것이 어떻게 작동하는지 보여줍니다.
scope: {name: '='}
양방향 데이터 바인딩을 사용할 때 (즉, '='를 사용할 때) 보간이 허용되지 않기 때문에 사용시 구문 오류가 발생합니다. 즉, {{}}를 사용할 수 없습니다. 대신에 <tabs name="{{name}}">
사용 <tabs name="name">
.
Using '@' works the same as the transclude case because ng-transclude uses the transcluded scope, not the isolate scope that is created by using scope: { ... }
.
For (lots) more information about scopes (including pictures) see
What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
I believe that the problem has to do with scoping. Initially the inner textbox doesn't have name
set, so it is inherited from the outer scope. This is why typing in the outer box is reflected in the inner box. However, once typing in the inner box occurs, the inner scope now contains name
which means it is no longer bound to the outer name
so the outer text box doesn't sync up.
The appropriate way to fix is only storing models in the scope, not your values. I fixed it in http://jsfiddle.net/pdgreen/5RVza/ The trick is to create a model object (data
) and referencing values on it.
The incorrect code modifies the scope in the directive, the correct code modifies the model in the scope in the directive. This subtle difference allows the scope inheritance to work properly.
I believe the way Miško Hevery phrased it was, scope should be write-only in the controller, and read-only in directives.
update: reference: https://www.youtube.com/watch?v=ZhfUv0spHCY#t=29m19s
구문 오류는 무언가를 잘못 썼음을 의미합니다. 특정 프레임 워크 / 라이브러리와 관련이 없습니다. ","를 추가하거나 괄호를 닫는 것을 잊었을 것입니다. 다시 확인하세요
'IT Share you' 카테고리의 다른 글
Xcode Guard Malloc 및 장치 디버깅 : 'libgmalloc.dylib'이미지를 찾을 수 없음 (0) | 2020.12.10 |
---|---|
iOS, Android 및 WP에서 개발하는 데 드는 비용은 얼마입니까? (0) | 2020.12.10 |
다른 루트 디렉토리에 대해 xampp 웹 서버를 구성하는 방법 (0) | 2020.12.10 |
데이터 프레임의 각 그룹 내에서 최대 값 추출 (0) | 2020.12.10 |
git pull 및 git push에 대한 다른 기본 원격 (추적 분기) (0) | 2020.12.10 |