Instead of viewing the $submitted property, you can create a directive that has the same name as the form directive, which is associated with an event handler for the form that passes the angular event, which you can listen to in your myDirective directive. You do not need to worry about overriding the implementation of the angular form directive, it will just add your behavior without overwriting the inline implementation.
Demo
Note. You can also not add functionality to the form directive and instead choose a different directive name, just be sure to attach this directive name as an attribute in the form tag to trigger an event.
Javascript
.directive('form', function() { return { restrict: 'E', link: function(scope, elem) { elem.on('submit', function() { scope.$broadcast('form:submit'); }); } }; }) .directive('myDirective', function() { return { require: '^form', link: function(scope, elem, attr, form) { scope.$on('form:submit', function() { form.$setPristine(); }); } }; });
Update
In light of the issue raised in the comment below:
what is the most efficient way to check if there is an element that has the my-directive attribute has the "my-form" (if I call the "form" directive "myForm") attribute in it of the parent form? Therefore, I can either use "myDirective" with or without "myForm" (and behave accordingly, of course)
There are several ways to do this:
- Use the
.data() method in your myForm directive at compile time and access it in the link function in myDirective using the .inheritedData() method if there is data assigned in the form directive.
Note that I passed the form controller in the broadcast in the myForm directive. This ensures that you get the controller of the parent form, which is the form element. There are certain use cases in which you must use myDirective inside a nested form via ng-form , so instead of setting form.$setPristine() to the form element of the form element, you must install the ngForm form ngForm .
Demo
.directive('myForm', function() { return { require: 'form', compile: function(tElem, tAttr) { tElem.data('augmented', true); return function(scope, elem, attr, form) { elem.on('submit', function() { scope.$broadcast('form:submit', form); }); } } }; }) .directive('myDirective', function() { return { link: function(scope, elem, attr) { if(!elem.inheritedData('augmented')) { return; } scope.$on('form:submit', function(event, form) { console.log('submit'); form.$setPristine(); }); } }; });
- Another way, which is probably very optimized for this particular use case. To create a controller in the
myForm directive, which stores form event handlers that will iterate when the form event fires. Instead of using the $broadcast angular event, which is actually slower than the implementation below, because it traverses every area from the form element to the last chain of scope. The myForm controller below creates its own mechanism for storing event handlers. As implemented in # 1, using .data() - inheritedData() slow when myDirective deeply immersed and myDirective from a large number of elements, as it crosses the DOM up until it finds a specific data . Using the implementation below, you can check if the required controller exists in the parent ?^myForm , pay attention to ? It is an optional requirement. In addition, setting the scope to true in the myForm directive allows you to reuse the directive, for example. have several myForm directives inside the page.
Demo
.directive('myForm', function() { return { require: ['form', 'myForm'], scope: true, controller: function() { this.eventHandlers = { submit: [], change: [] }; this.on = function(event, handler) { if(this.eventHandlers[event]) { this.eventHandlers[event].push(handler); } }; }, link: function(scope, elem, attr, ctrls) { var form = ctrls[0], myForm = ctrls[1]; angular.forEach(myForm.eventHandlers, function(handlers, event) { elem.on(event, function(eventObject) { angular.forEach(handlers, function(handler) { handler(eventObject, form); }); }); }); } }; }) .directive('myDirective', function() { return { require: '?^myForm', link: function(scope, elem, attr, myForm) { if(!myForm) { return; } myForm.on('submit', function(event, form) { console.log('submit'); form.$setPristine(); }); } }; });