user2360062
user2360062

Reputation: 703

Unable to watch form $dirty (or $pristine) value in Angular 1.x

I have a scenario in an Angular 1.x project where I need to watch a controller form within a directive, to perform a form $dirty check. As soon as the form on a page is dirty, I need to set a flag in an injected service.

Here is the general directive code:

            var directiveObject = {
            restrict: 'A',
            require: '^form',
            link: linkerFn,
            scope: {
                ngConfirm: '&unsavedCallback'
            }
        };

        return directiveObject;

        function linkerFn(scope, element, attrs, formCtrl) {
          ...

            scope.$watch('formCtrl.$dirty', function(oldVal, newVal) {
              console.log('form property is being watched');
          }, true);               

          ...
        }

The above only enters the watch during initialization so I've tried other approaches with the same result:

watching scope.$parent[formName].$dirty (in this case I pass formName in attrs and set it to a local var formName = attrs.formName)

watching element.controller()[formName] (same result as the above)

I've looked at other SO posts regarding the issue and tried the listed solutions. It seems like it should work but somehow the form reference (form property references) are out of scope within the directive and therefore not being watched.

Any advice would be appreciated. Thank you.

Upvotes: 4

Views: 1836

Answers (1)

Lex
Lex

Reputation: 7194

I don't know why that watch isn't working, but as an alternative to passing in the entire form, you could simply pass the $dirty flag itself to the directive. That is:

.directive('formWatcher', function() {
    restrict: 'A',
    scope: {
        ngConfirm: '&unsavedCallback', // <-- not sure what you're doing with this
        isDirty: '='
    },
    link: function(scope, element, attrs) {
        scope.watch('isDirty', function(newValue, oldValue) {
            console.log('was: ', oldValue);
            console.log('is: ', newValue);
        });
    }
})

Using the directive:

<form name="theForm" form-watcher is-dirty="theForm.$dirty">
    [...]
</form>

Upvotes: 3

Related Questions