Pass form to directive

前端 未结 5 2115
盖世英雄少女心
盖世英雄少女心 2020-11-30 19:35

I want to encapsulate my form fields in a directive so I can simply do this:

5条回答
  •  -上瘾入骨i
    2020-11-30 20:08

    Edit 2: I'll leave my answer, as it might be helpful for other reasons, but the other answer from Mark Rajcok is what I originally wanted to do, but failed to get to work. Apparently the parent controller here would be form, not ngForm.


    You can pass it in using an attribute on your directive, although that will get rather verbose.

    Example

    Here's a working, simplified jsFiddle.

    Code

    HTML:

    Essential parts of the directive:

    app.directive('myInput', function() {
        return {
            scope: {
                form: '='
            },
            link: function(scope, element, attrs) {
                console.log(scope.form);
            }
        };
    });
    

    What's happening

    We've asked Angular to bind the scope value named in the form attribute to our isolated scope, by using an '='.

    Doing it this way decouples the actual form from the input directive.

    Note: I tried using require: "^ngForm", but the ngForm directive does not define a controller, and cannot be used in that manner (which is too bad).


    All that being said, I think this is a very verbose and messy way to handle this. You might be better off adding a new directive to the form element, and use require to access that item. I'll see if I can put something together.

    Edit: Using a parent directive

    OK, here's the best I could figure out using a parent directive, I'll explain more in a second:

    Working jsFiddle using parent directive

    HTML:

    JS (partial):

    app.directive('myForm', function() {
        return {
            restrict: 'E',
            scope: {
                form: '='
            },
            controller: ['$scope', function($scope) {
                this.getForm = function() {
                    return $scope.form;
                }
            }]
        }
    });
    
    app.directive('myInput', function() {
        return {
            require: '^myForm',
            link: function(scope, element, attrs, myForm) {
                console.log(myForm.getForm());
            }
        };
    });
    

    This stores the form in the parent directive scope (myForm), and allows child directives to access it by requiring the parent form (require: '^myForm'), and accessing the directive's controller in the linking function (myForm.getForm()).

    Benefits:

    • You only need to identify the form in one place
    • You can use your parent controller to house common code

    Negatives:

    • You need an extra node
    • You need to put the form name in twice

    What I'd prefer

    I was trying to get it to work using an attribute on the form element. If this worked, you'd only have to add the directive to the same element as ngForm.

    However, I was getting some weird behavior with the scope, where the myFormName variable would be visible within $scope, but would be undefined when I tried to access it. That one has me confused.

提交回复
热议问题