Getting ngModelController input
I need to access the ngModelController of an input element to check if it is dirty or intact.
I managed to do this with a directive that grabs the ngModel of the input of the data object associated with the element, making it accessible from anywhere:
app.directive("input", [ function () {
return {
restrict: "E",
replace: false,
scope: false,
require: "ngModel",
link: function (scope, element, attrs, ctrls) {
element.data('ngModelController', ctrls);
}
}
}])
I know it can be modified to make the directive an attribute, making it less related to the "input" tag.
I use these stored controllers in directives that represent UI elements and have elements input
in their markup. I don't use forms because these elements should work in any dom context, and forms imply certain restrictions on the hierarchy. So I am using ngModelController to check some of the things needed to validate the fields.
But is there a better way to get the ngModelController of a specific input?
source to share
In my experience Angular provides this for you already. In your directive where you want to access the ngModelController do the following:
app.directive("randomDirective", function() {
return {
...
require: "ngModel",
link: function(scope, element, attrs, ctrl) {
var someInput = element.find('theInput'),
ngModelCtrlForInput = someInput.data().$ngModelController;
//Now you can access the ngModel controller for the <input> of the directive
}
}
});
Whether this is the best way to accomplish this feat remains to be seen. I haven't seen any better answers yet (but if you know anyone, ping me and let me know!).
EDIT
There are other options in this answer , including similar ones:
element.find('theInput').controller('ngModel')
source to share
Apparently it wasn't enough for the OP to only use the ngModelController **, which angular already provides you ** (when you do require
). As described in the documentation :
To take control of a controller, you use
require
itdirective
as shown in the example below.
Indeed, the OP and the highest answer at this point, both are already doing it! ... But then they do more; they either set or get using various methods that rely on data
being attached to the DOM element using angular jqLite which overrides jQuery which refers to the Dataset API
This may be required if you want to access the controller outside of the angular framework; that is, the jQuery extension can reach the controller. After all, the OP had a goal of "making it accessible from anywhere." But if you managed to use only angular then there is no need to use the data attribute.
However, I think it's worth considering: if you want to access ngModelController
for a specific purpose, you've already done so! that is, you can:
- make
directive
for this purpose - required
"ngModel"
how everyone did - manipulate the argument
ctrl
passed to the functionlink
* or the corresponding element if require is an array and therefore ctrl is an array
There is no need to set in an object data()
, and so there is no reason to get from an object data()
if you can just apply a different directive. Indeed, this requires
is one of the patterns described to support a "directive for directive communication":
app.directive("purpose1", [ function () {
return {
require: "ngModel",
link: function (scope, element, attrs, ngModelCtrl) {
And some other target can still hit ngModelCtrl
:
app.directive("purpose2", [ function () {
return {
require: "ngModel",
link: function (scope, element, attrs, ngModelCtrl) {
I myself want to exclude this directive entirely, so I was hoping there was another more direct access to ngModelController.
source to share