Search code examples
javascriptjqueryangularjsangularjs-serviceangular-services

How to observe or watch an input attribute change in an AngularJS Service?


I have a radio button in my UI that has an ngModel and it enable/disable another input through ngDisabled.

I want to observer/watch/trigger when an input element become enabled/disabled and it has to be done in an Angular Service. I simply can't find how to do that. Here is how I would do it in a Directive:

// for the case of field that might be ng-disabled, we should skip validation
// Observe the angular disabled attribute
attrs.$observe("disabled", function(disabled) {
  if (disabled) {
    // Turn off validation when element is disabled
    cancelValidation();
  } else {
    // Re-Validate the input when enabled
    var value = ctrl.$viewValue || '';
    ctrl.$setValidity('validation', validate(value, true));
  }
});

But how to do it in a Service???
I do not wish to have another Directive, I really want it done through the Service.

Before asking the question, I found this Is it possible to 'watch' attributes' changes and I tried it

scope.$watch(function() {return element.attr('disabled'); }, function(newValue){});

but that does not seem to work, at least not when I enable/disable my radio button (the input element as an ngDisabled that is bind to the radio button with an ngModel)

I also found that we could possible use jQuery.watch() but I want to stick with vanilla javascript or jqLite. Is it possible?

EDIT
I should have mentioned that this Service is on it's own and does not have access to the Controller, because it's a Form validation tool and it does not know about the outside (at least not more than the element itself and his scope). You can check it out and use it if you want: Angular-Validation and it support Directive and Service depending on what or where you want the validation to happen and my problem was related to the code in the Service only. The answer from pankajparkar helped me solved it... Thanks :)


Solution

  • I believe you had attribute disabled with an interpolation something like disabled="{{disable}}" that why you were able to put $observe on that value try changing the same thing to $watch will not work on that attribute, you need to additionally need $interpolate service to evaluate you attribute interpolation. So that the actually value will get evaluate is it disabled or '' and if changes it state then $watch function will get fired accordingly.

    Code

    scope.$watch(function() {
       return $interpolate(element.attr('disabled'))(scope); //this will evaluate attribute value `{{}}``
    }, function(newValue){
        //your code would be here
    });