Programing

격리 범위를 사용하여 내부 지시문에서 $ watch ngModel

lottogame 2021. 1. 9. 09:20
반응형

격리 범위를 사용하여 내부 지시문에서 $ watch ngModel


내 연결 기능 내부에서 내 모델 값을 보려고합니다.

scope.$watch(attrs.ngModel, function() {
       console.log("Changed"); 
    });

컨트롤러 내부의 모델 값을 변경하면 $ watch 함수가 트리거되지 않습니다.

$scope.myModel = "ACT";

$timeout(function() {
   $scope.myModel = "TOTALS"; 
}, 2000);

바이올린 : http://jsfiddle.net/dkrotts/BtrZH/4/

내가 여기서 무엇을 놓치고 있습니까?


문제는 당신이 있다는 것입니다 $watch보내고 attrs.ngModel"myModel"과 동일하다. 범위에 "myModel"바인딩이 없습니다. 당신은 $watch"모델"을 원합니다 . 그것이 당신의 지시문의 범위에 묶여있는 것입니다. http://jsfiddle.net/BtrZH/5/ 참조


보고있는 $ modelValue를 반환하는 함수를 주시해야합니다.

다음 코드는 기본 예를 보여줍니다.

app.directive('myDirective', function (){
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
           scope.$watch(function () {
              return ngModel.$modelValue;
           }, function(newValue) {
               console.log(newValue);
           });
        }
     };
});

여기 에 동일한 아이디어가 실행되고 있습니다.


이를 수행하는 적절한 방법은 다음과 같습니다.

app.directive('myDirective', function () {
  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {

        ngModel.$render = function () {
            var newValue = ngModel.$viewValue;
            console.log(newValue)
        };

    }
  };
});

이를 수행하는 또 다른 방법은 다음과 같습니다.

app.directive('myDirective', function (){
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
           attrs.$observe('ngModel', function(value){ // Got ng-model bind path here
              scope.$watch(value,function(newValue){ // Watch given path for changes
                  console.log(newValue);  
              });
           });
        }
    };
});

Doing it that way you will be able to listen value changes with binds like that


This is an extension of @ Emmanuel's answer above to answer @Martin Velez, although I know it's pretty late! (Also I can't make comments yet, so if this isn't the right place for this, sorry!)

I'm not sure which version of Angular OP was using, but in Angular#1.2+ at least on the official docs https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$render, $render is listed like this:

Called when the view needs to be updated. It is expected that the user of the ng-model directive will implement this method.

The $render() method is invoked in the following situations:

$rollbackViewValue() is called. If we are rolling back the view value to the last committed value then $render() is called to update the input control. The value referenced by ng-model is changed programmatically and both the $modelValue and the $viewValue are different from last time. Since ng-model does not do a deep watch, $render() is only invoked if the values of $modelValue and $viewValue are actually different from their previous value.

I interpret this to mean that the correct way to $watch an ngModel from a directive is to require ngModel and implement a link function that injects ngModelController. Then use the ngModel API that's built in to $render-on-change ($watch), or whatever else.


There are 2 ways to do it.

1) You can use $attrs.[any_attribute] and set on it any listener

2) You can have isolated scope with 2 ways binding variable and set a listener on it.If you want more,here is a cool article

http://www.w3docs.com/snippets/angularjs/bind-variable-inside-angularjs-directive-isolated-scope.html

ReferenceURL : https://stackoverflow.com/questions/14693052/watch-ngmodel-from-inside-directive-using-isolate-scope

반응형