I wrote a custom angular-js directive that asks for user confirmation when navigating away from forms that are half-filled and unsaved.
It works perfectly well but I'm not sure I understand what I'm doing.
The code looks like so:
HTML:
<input type="text" name="username" form-confirmation/>
app.js:
angular.module('myModule').directive('formConfirmation', formConfirm)
function formConfirm() {
return {
restrict: 'A',
link: function ($scope, $element, $attrs) {
function conf(event) {
if ($scope[$element.attr('name')].$dirty) {
if (confirm("You have unsaved changes! Are you sure you wish to leave this page?") !== true) {
event.preventDefault();
}
}
};
$scope.$on('$locationChangeStart', conf);
}
}
}
My questions:
1) I tried first using if($element.$dirty) but this didn't work. How is $element different from $scope[$element.attr('name')] ?
2) What is the relationship between $element, $attrs, and $scope?
3) Where did $element's attr method come from?
答案 0 :(得分:3)
They are related by the element that existed in the DOM and caused AngularJS to execute a compile operation on that element because of the presence of the directive (in this case form-confirmation
).
All of these items's definitions are easily found in the directive documentation under Creating a Directive that Manipulates the DOM for the link function:
- scope is an Angular scope object.
- element is the jqLite-wrapped element that this directive matches.
- attrs is a hash object with key-value pairs of normalized attribute names and their corresponding attribute values.
- controller is the directive's required controller instance(s) or its own controller (if any). The exact value depends on the directive's require property.
- transcludeFn is a transclude linking function pre-bound to the correct transclusion scope.
To break your questions down further:
I tried first using if($element.$dirty) but this didn't work. How is $element different from $scope[$element.attr('name')] ? You are indexing a property on the $scope object based off of the presence of a specific attribute living on the $element.
What is the relationship between $element, $attrs, and $scope? They are related via the compiled DOM element that contained your directive.
Where did $element's attr method come from? Since $element is a jqLite wrapper for the DOM element, it is simply exposing the attributes that exist on the actual DOM note as the attr property.
I highly recommend that you thoroughly read and digest the directive documentation I linked above. It contains a wealth of knowledge that will help you understand how directives work, which is a core piece of AngularJS.