Getting ngModelController of the input

巧了我就是萌 提交于 2019-12-07 07:59:00

问题


I need to access ngModelController of input element to check is it dirty or pristine.

I've managed to do it with directive which grabs ngModel of input to data object associated with element, making it obtainable 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 could be modified to make directive as attribute, making it less coupled to 'input' tag.

I use that saved controllers in directives which represent UI elements and have input elements in their markup. I don't use forms because those elements should work in any dom context, and forms imply certain limitations to hierarchy. So i'm using ngModelController to check some stuff required for validation of fields.

But is there any better way to get ngModelController of certain input?


回答1:


In my experience, Angular provides this to 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 of one please ping me and let me know!).

EDIT

This answer has some other options, including something similar to:

element.find('theInput').controller('ngModel')



回答2:


Apparently it was not sufficient for the OP to just use the ngModelController ** which angular already provides to you** (when you require it). As described in the documentation:

To get a hold of the controller, you require it in the directive as shown in the example below.

Indeed, the OP and the highest-voted answer at this point, both already do this!. But then they do more; they either set, or get, using various techniques which rely on the data attached to the DOM element using angular's jqLite, which defers to jQuery's, which defers to the Dataset API

These might be necessary if you want to access the controller outside of the angular framework; i.e. a jQuery extension could reach the controller. After all, the OP did have a goal of "making it obtainable from anywhere". But if you've managed to use angular exclusively, then there's no need to use teh data attribute.

However, I think it's worth calling out: that if you want to access the ngModelController for a specific purpose, you've already done it! i.e. you can:

  1. make a directive for that purpose
  2. require "ngModel" as everyone has done
  3. manipulate the ctrl argument* passed to the link function

*or the appropriate element if require is an array , and therefore ctrl is an array

There is no need to set on the data() object, and therefore no reason to get from the data() object if you can just apply another directive. Indeed, requires is one of the patterns described to support "directive to directive communication":

app.directive("purpose1", [ function () {
    return {
        require: "ngModel",
        link: function (scope, element, attrs, ngModelCtrl) {

And some other purpose can still get at the ngModelCtrl:

app.directive("purpose2", [ function () {
    return {
        require: "ngModel",
        link: function (scope, element, attrs, ngModelCtrl) {

I myself want to avoid the directive altogether, so I was hoping there was an even more direct way to access the ngModelController.



来源:https://stackoverflow.com/questions/26299710/getting-ngmodelcontroller-of-the-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!