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?

+3


source to share


2 answers


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')

      

+4


source


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

it directive

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.

0


source







All Articles