커스텀 디렉티브의 ng-change 구현 방법
이런 템플릿이 있는 지시가 있어요
<div>
<div ng-repeat="item in items" ng-click="updateModel(item)">
<div>
내 지시사항은 다음과 같이 선언됩니다.
return {
templateUrl: '...',
restrict: 'E',
require: '^ngModel',
scope: {
items: '=',
ngModel: '=',
ngChange: '&'
},
link: function postLink(scope, element, attrs)
{
scope.updateModel = function(item)
{
scope.ngModel = item;
scope.ngChange();
}
}
}
나는 가지고 싶다ng-change
항목이 클릭되고 값이 지정되면 호출됩니다.foo
는 이미 변경되었습니다.
즉, 내 지시가 다음과 같이 구현되는 경우:
<my-directive items=items ng-model="foo" ng-change="bar(foo)"></my-directive>
전화할 수 있을 것 같습니다.bar
가치가 있을 때foo
가 갱신되었습니다.
상기의 코드와 함께,ngChange
호출은 성공했지만 오래된 값으로 호출됩니다.foo
새로 갱신된 값 대신.
문제를 해결하는 한 가지 방법은 전화하는 것입니다.ngChange
미래의 어느 시점에서 실행할 타임아웃 내의 값foo
는 이미 변경되었습니다.그러나 이 솔루션에서는 실행 순서를 제어할 수 없기 때문에 보다 우아한 솔루션이 필요하다고 생각합니다.
감시자가 필요할 수도 있어요foo
하지만 이 솔루션에서는 실제적인 영향을 주지 않습니다.ngChange
그 방법, 그리고 나는 시청자들이 기억력을 많이 소비한다고 들었다.
어떻게 할 수 있을까요?ngChange
타임아웃이나 워처 없이 동기적으로 실행됩니까?
예: http://plnkr.co/edit/8H6QDO8OYiOyOx8efhyJ?p=preview
필요한 경우ngModel
그냥 전화하면 돼$setViewValue
에서ngModelController
은 암묵적으로 평가됩니다.ng-change
링크 함수의 네 번째 파라미터는 ngModelCtrl이어야 합니다.다음 코드는ng-change
당신의 지시를 위해 일하세요.
link : function(scope, element, attrs, ngModelCtrl){
scope.updateModel = function(item) {
ngModelCtrl.$setViewValue(item);
}
}
솔루션이 작동하려면 myDirective의 격리 범위에서 ngChange 및 ngModel을 삭제하십시오.
다음은 http://plnkr.co/edit/UefUzOo88MwOMkpgeX07?p=preview의 장점입니다.
dr;dr
제 경험상 ngModelCtrl에서 상속받으면 됩니다.ng-change
메서드를 사용하면 식이 자동으로 평가됩니다.ngModelCtrl.$setViewValue
angular.module("myApp").directive("myDirective", function(){
return {
require:"^ngModel", // this is important,
scope:{
... // put the variables you need here but DO NOT have a variable named ngModel or ngChange
},
link: function(scope, elt, attrs, ctrl){ // ctrl here is the ngModelCtrl
scope.setValue = function(value){
ctrl.$setViewValue(value); // this line will automatically eval your ng-change
};
}
};
});
더 정확히 말하면
ng-change
평가됩니다.ngModelCtrl.$commitViewValue()
ngModel의 오브젝트 참조가 변경된 경우.방법$commitViewValue()
에 의해 자동으로 호출됩니다.$setViewValue(value, trigger)
trigger 인수를 사용하지 않거나 ngModelOptions를 사전 설정하지 않은 경우.
제가 지정한 것은ng-change
의 참조가 자동적으로 트리거 되는 경우, 자동적으로 트리거 됩니다.$viewValue
변경되었다.이 경우ngModel
는 입니다.string
또는int
,그것에 대해 염려하실 필요는 없어요.만약 당신이ngModel
오브젝트이며, 그 속성 중 일부를 변경하는 것 뿐입니다.$setViewValue
는 하지 않습니다.ngChange
.
투고 시작부터 코드 예를 들면
scope.setValue = function(value){
ctrl.$setViewValue(value); // this line will automatically evalyour ng-change
};
scope.updateValue = function(prop1Value){
var vv = ctrl.$viewValue;
vv.prop1 = prop1Value;
ctrl.$setViewValue(vv); // this line won't eval the ng-change expression
};
몇 가지 조사를 한 결과, 최선의 접근법은 다음과 같은 방법을 사용하는 것 같습니다.$timeout(callback, 0)
.
합니다.$digest
이치노
그래서 제 경우, 해결책은
$timeout(scope.ngChange, 0);
이렇게 하면 콜백의 시그니처가 무엇이든 상관없습니다.콜백은 부모 범위에서 정의한 대로 실행됩니다.
이러한 변경이 적용된 플렁커는 다음과 같습니다. http://plnkr.co/edit/9MGptJpSQslk8g8tD2bZ?p=preview
Samuli Ulmanen과 lucienBertin의 답변은 Angular에서 조금 더 읽기는 하지만 그것을 증명합니다.JS 문서에서는 이 처리 방법에 대한 추가 조언을 제공합니다(https://docs.angularjs.org/api/ng/type/ngModel.NgModelController) 참조).
특히 $setViewValue(myObj)에 객체를 전달하는 경우.각진JS 문서 상태:
표준 입력과 함께 사용할 경우 뷰 값은 항상 문자열이 됩니다(경우에 따라 입력의 Date 개체와 같은 다른 유형으로 구문 분석됩니다.그러나 사용자 지정 컨트롤이 개체를 이 메서드에 전달할 수도 있습니다.이 경우 $setViewValue에 전달하기 전에 오브젝트의 복사본을 만들어야 합니다.이는 ngModel이 객체의 상세 감시를 수행하지 않고 ID 변경만 찾기 때문입니다.객체의 속성만 변경하면 ngModel은 객체가 변경되었음을 인식하지 못하고 $pars 및 $validators 파이프라인을 호출하지 않습니다.따라서 $setViewValue로 전달된 복사본의 속성을 변경하지 마십시오.그렇지 않으면 스코프의 모델 값이 잘못 변경될 수 있습니다.
구체적인 경우 모델이 모멘트 날짜 객체이기 때문에 setViewValue를 호출하기 전에 먼저 객체를 복제해야 합니다.방법을 이 좋다: i한한 method method method i i i i i i i i i i i i i i i i i i i i i i i i 。var b = moment(a);
link : function(scope, elements, attrs, ctrl) {
scope.updateModel = function (value) {
if (ctrl.$viewValue == value) {
var copyOfObject = moment(value);
ctrl.$setViewValue(copyOfObject);
}
else
{
ctrl.$setViewValue(value);
}
};
}
는 기본 것은 모델이 업데이트되지 않는 입니다. 즉, 기본 모델은 업데이트되지 않고 나중에 이 발생한다는 것입니다.scope.updateModel
실행이 완료되었습니다. 경우,ngChange
에 대한 내용을 세부 .ngChange
이미 적용된 모델 업데이트에 의존하는 것이 아니라
은, 「」, 「」를 호출했을 에, 로컬 할 수 .ngChange
. 값을 ""에서 할 수 있는 수 ng-change
★★★★★★ 。
예를 들어 다음과 같습니다.
scope.updateModel = function(item)
{
scope.ngModel = item;
scope.ngChange({newValue: item});
}
HTML에서:
<my-directive ng-model="foo" items=items ng-change="bar(newValue)"></my-directive>
참조: http://plnkr.co/edit/4CQBEV1S2wFFwKWbWec3?p=preview
언급URL : https://stackoverflow.com/questions/24754005/how-to-implement-an-ng-change-for-a-custom-directive
'programing' 카테고리의 다른 글
Springboot / Angular 2 - HTML5 URL 처리 방법 (0) | 2023.04.06 |
---|---|
TypeScript의 '확장'과 '실장'의 차이점은 무엇입니까? (0) | 2023.04.06 |
구텐베르크에 블록을 '수동'(프로그래밍 방식으로) 삽입하려면? (0) | 2023.04.06 |
Angular 템플릿의 인라인 로직JS (0) | 2023.04.06 |
woocommerce_update_product 액션– 제품 업데이트마다 한 번만 실행 (0) | 2023.04.06 |