AngularJS ng-model不能处理动态创建的输入字段

时间:2014-09-03 00:52:53

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-model

我为表单字段创建了一个动态templateUrl,我正在尝试在ng-repeat中附加ng-model。父指令和表单字段指令都可以生成并生成,但是当我使用ng-model它似乎没有工作时,预输出永远不会改变?在这个用例中应用ng-model有诀窍吗?如果我只是使用硬编码表单输入,它的工作原理。我一直在关注AngularJS文档中的example

表单字段周围的标记:

<form role="form" ng-controller="FormController as formCtrl" novalidate>

    <div ng-repeat="field in panel.form_fields">

        <form-field field="field"></form-field>

    </div>

    <fieldset class="form-group clearfix">
        <button type="submit" class="btn btn-primary pull-right">Save Progress</button>
    </fieldset>

    <pre>form   = {{models | json}}</pre>
    <pre>master = {{master | json}}</pre>
</form>

表单字段指令:

angular.module('formField.directives', [])

.directive('formField', [ '$http', '$compile', function( $http, $compile ) {

    var getTemplateUrl = function( field ) {

        var type = field.field_type;
        var templateUrl = '';

        switch( type ) {
            case 'textfield':
                templateUrl = 'components/form-field/fields/textfield.html';
                break;
            case 'email':
                templateUrl = 'components/form-field/fields/email.html';
                break;
            case 'currency':
                templateUrl = 'components/form-field/fields/currency.html';
                break;
            case 'date':
                templateUrl = 'components/form-field/fields/date.html';
                break;
            case 'dropdown':
                templateUrl = 'components/form-field/fields/dropdown.html';
                break;
            case 'textarea':
                templateUrl = 'components/form-field/fields/textarea.html';
                break;
            case 'hidden':
                templateUrl = 'components/form-field/fields/hidden.html';
                break;
            case 'password':
                templateUrl = 'components/form-field/fields/password.html';
                break;
            case 'checkbox':
                templateUrl = 'components/form-field/fields/checkbox.html';
                break;
            case 'radio':
                templateUrl = 'components/form-field/fields/radio.html';
                break;
        }

        return templateUrl;
    }

    var linker = function( scope, element ) {

        var templateUrl = getTemplateUrl( scope.field );
        $http.get( templateUrl ).success(function( data ) {
            element.html(data);
            $compile(element.contents())(scope);
        });
    }

    return {
        restrict: 'E',
        replace: true,
        scope: {
            field: '='
        },
        link: linker
    }
}]);

使用的表单字段模板:

<fieldset class="form-group">

    <label for="{{field.field_name}}">{{field.field_label}}</label>
    <input type="text" 
           class="form-control"
           id="{{field.field_id}}"
           name="{{field.field_name}}"
           value="{{field.field_value}}"
           placeholder="{{field.field_prompt}}"
           ng-required="field.field_required"
           ng-disabled="field.field_disabled"
           ng-model="models[field.field_name]"> // model.test also doesn't work, and need to be able to reference the model dynamically

</fieldset>

AngularJS docs中的示例使用的控制器:

.controller('FormController', ['$scope', function( $scope ) {

    $scope.master = {};
    $scope.models = {};

    $scope.update = function( models ) {
        console.info('Update');
        $scope.master = angular.copy( models );
    };

    $scope.submit = function() {
        console.info('Form Submitted');
    };

    $scope.cancel = function() {
        console.info('Form Cancelled');
    };

    $scope.clear = function() {
        console.info('Form Clear');
        $scope.models = {};            
    }

    $scope.reset = function() {
        console.info('Form Reset');
        $scope.models = angular.copy( $scope.master );
    };

    $scope.reset();

}]);

1 个答案:

答案 0 :(得分:3)

您的指令适用于隔离范围(.$new(true)),这意味着您在指令中所做的更改将无法直接在外部作用域中使用(除非您使用双向绑定等)。因此,ng-model="models[field.field_name]"指令中的models不是父控制器中作用域上的models对象。所以你可以通过使用双向绑定传递模型来修复它。

消费时: -

 <form-field field="field" model="models[field.field_name]"></form-field>

在您的指令模板中: -

   <input type="text" 
       class="form-control"
       id="{{field.field_id}}"
       name="{{field.field_name}}"
       value="{{field.field_value}}"
       placeholder="{{field.field_prompt}}"
       ng-required="field.field_required"
       ng-disabled="field.field_disabled"
       ng-model="model">  <!-- Here just set the model on the scope 2-way B -->

并在您的指令中隔离范围声明: -

  scope:{field:'=', model:'='},
  //or set a reference to the object on scope holding models in the field property itself.

<强> Plnkr

请注意,在指定value="{{field.field_value}}"ng-model时,在指令模板中,根本不会设置默认值。您需要在ngModel本身中默认它。