AngularJS - Modular forms with directives

后端 未结 1 854
遇见更好的自我
遇见更好的自我 2021-02-03 12:09

I originally asked this question here, but I think I got ahead of myself and made it more complicated than it really is, so I\'m re-asking it here with a bit clearer wording.

1条回答
  •  南笙
    南笙 (楼主)
    2021-02-03 12:23

    Angular comes out of the box with an improve tag that is documented here. Basically it creates a scope in the form of a controller around the form and all of the tags within it. So you do this:

    
    

    JS:

    var app = angular.app('TestApp', []);
    app.controller('FormCtrl', function($scope) {
        $scope.submit = function() {
            // Form submit logic here
            console.log("Submitting the form");
            console.log($scope);
        }
    })
    

    This creates a scope for the form, since the form tag contains the ng-controller tag. Within the scope, testForm is the javascript object for the form, and testForm.firstInput is the javascript object for the first input. It looks like these objects also have some validation functionality available, see docs here.

    The data on the form will be available as an object data in the FormCtrl scope, with keys "first" and "second", and you can define methods in the controller that work on that.

    You can also put multiple forms using the same FormCtrl, and it seems like Angular will create new instances for each form, so you don't have to worry about forms polluting each other's data.

    Using directives

    Now lets suppose that we have some sort of complex input or widget that is implemented in a directive. This example uses two select boxes to display all cities in a state. You have to first select a state, then it'll query for the cities in that state and populate the second select box.

    app.directive('citySelect', function() {
        return {
            replace: true,
            template: '
    ' + '', controller: function($scope) { // Omitting the logic for getCities(), but it'd go here } }; })

    Then you can just stick it into the form tag, and it'll work. Because the directive doesn't define a scope, it'll just attach to the scope of the FormCtrl.

    
    

    Paramaterizing the directives

    EDIT: So apparently this does work:

    scope: {someParameter: "="},
    template: '
    '

    You simply do it without the curlies, and it'll bind. My guess is that the parent scope is binding to someParameter in the child scope, and the select is then binding to somParameter in the child scope.

    So all of this below about manually compiling in the link function is not necessary.

    =====

    But the problem with this is that my citySelect directive has a hard coded ng-model binding, so if I created some sort of generic widget, I couldn't use more than one of it in a form. Unfortunately this does not seem to work:

    scope: {someParameter: "="},
    template: '
    '

    The only way that I have gotten this to work is to build the DOM element manually in a linking function, but I'm not sure if this is advisable. I would appreciate comments from anyone about this implementation:

    
    
    app.directive('citySelect', function($compile) { return { replace: true, template: '
    ', controller: function($scope) { // Omitting the logic for getCities(), but it'd go here } link: function(scope, iElem, iAttrs) { var html = '
    提交评论

提交回复
热议问题