javascript - AngularJS ng-model 不适用于动态创建的输入字段

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

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

表单字段周围的周围标记:

<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 文档中示例中使用的 Controller :

.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();

}]);

最佳答案

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

食用时:-

 <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 本身中默认它。

关于javascript - AngularJS ng-model 不适用于动态创建的输入字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25634602/

相关文章:

Javascript 在 JSON 对象中递归查找

javascript - 如何在基础对象上声明数据结构,以便它们在每个扩展对象中保持独立?

Javascript 根据星期几隐藏/显示 div?

javascript - Angularjs - 多个 API 调用的正确方法是什么

javascript - 对 JSON 数组进行过滤和排序

javascript - John Resig 的 "Simple Javascript Inheritance"还可以吗?

javascript - 解析后如何通过回调将内容从服务传递到另一个服务到 Controller ?

AngularJS 访问指令模板内的 DOM 元素

angularjs - 如何测试 Angular 事件?

javascript - AngularJS : How do access parent controller's scope item from the child directive?