本文介绍了AngularJS:动态添加的字段未在 FormController 上注册的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 AngularJS 中有以下 静态 表单:

<label>名字:</label><input type="text" name="first_name" ng-model="entity.first_name"><label>姓氏:</label><input type="text" name="last_name" ng-model="entity.last_name"></表单>

Angular 为我创建了一个 FormController 并将其发布到范围内(在表单名称下).这意味着我可以访问如下属性:

$scope.myForm.first_name.$error$scope.myForm.last_name.$invalid...

这个超级有用!

但就我而言,我正在动态构建一个表单,使用指令:

<field which="first_name"></field><field which="last_name"></field></表单>

指令直到一段时间后才解析为实际的 元素(在我从服务器获取一些数据之后,链接指令等).

这里的问题是表单控制器上没有定义任何字段属性,就像动态字段没有注册到 FormController 一样:

//以下属性未定义(但 $scope.myForm 存在)$scope.myForm.first_name$scope.myForm.last_name

知道为什么吗?任何解决方案/解决方法?

你可以在这个jsFiddle中看到完整的代码:
http://jsfiddle.net/vincedo/3wcYV/

解决方案

Update 7/31/2015 此问题自 1.3 以来已修复,请参阅此处:https://github.com/angular/angular.js/issues/1404#issuecomment-125805732>

原始答案不幸的是,这是目前 AngularJS 的一个短板.Angular 的表单验证不适用于动态命名的字段.您可以在 HTML 底部添加以下内容以准确查看发生了什么:

<pre>{{myForm|json}}</pre>

如您所见,Angular 没有正确获取动态输入名称.目前有一个涉及嵌套表单的工作,这可能会变得有点讨厌,但它确实有效,并且(需要一些额外的工作)可以毫无问题地提交父表单.

如果你愿意,你可以为这个问题争取更多支持:GitHub Issue -动态元素验证.无论哪种方式,这是代码:

http://jsfiddle.net/langdonx/6H8Xx/2/

HTML:

<div data-ng-controller="MyController"><form id="my_form" name="my_form" action="/echo/jsonp/" method="get"><div data-ng-repeat="form.data.fields 中的字段"><ng-form name="表单"><label for="{{ field.name }}">{{ field.label }}:</label><input type="text" id="{{ field.name }}" name="{{field.name}}" data-ng-model="field.data" required><div class="validation_error" data-ng-show="form['\{\{field.name\}\}'].$error.required">不能为空.</div></ng-form>

<输入类型=提交"/></表单>

JavaScript:

MyController.$inject = ["$scope"];函数 MyController($scope) {$scope.form = {};$scope.form.data = {};$scope.form.data.fields = []无功 f1 = {"name": "input_1","label": "我的标签 1",数据": ""};无功 f2 = {"name": "input_2","label": "我的标签 2",数据": ""};$scope.form.data.fields.push(f1);$scope.form.data.fields.push(f2);}

I have the following static form in AngularJS:

<form name="myForm" class="form-horizontal">

  <label>First Name:</label>
  <input type="text" name="first_name" ng-model="entity.first_name">

  <label>Last Name:</label>
  <input type="text" name="last_name" ng-model="entity.last_name">

</form>

Angular creates a FormController for me and publishes it into the scope (under the form name). Which means I have access to properties like the following:

$scope.myForm.first_name.$error
$scope.myForm.last_name.$invalid
...

This is super useful!

But in my case I'm building a form dynamically, using directives:

<form name="myForm" class="form-horizontal">

  <field which="first_name"></field>
  <field which="last_name"></field>

</form>

The <field> directives don't resolve to actual <input> elements until after a while (after I've fetched some data from the server, linked the directives, etc.).

The problem here is that no field properties are defined on the form controller, as if dynamic fields didn't register with the FormController:

// The following properties are UNDEFINED (but $scope.myForm exists)
$scope.myForm.first_name
$scope.myForm.last_name

Any idea why? Any solution/workaround?

You can see the entire code in this jsFiddle:
http://jsfiddle.net/vincedo/3wcYV/

解决方案

Update 7/31/2015 This has been fixed since 1.3, see here: https://github.com/angular/angular.js/issues/1404#issuecomment-125805732

Original AnswerThis is unfortunately a short coming of AngularJS at the moment. Angular's form validation doesn't work with dynamically named fields. You can add the following at the bottom of your HTML to see exactly what's going on:

<pre>{{myForm|json}}</pre>

As you can see, Angular isn't getting the dynamic input name right. There's currently a work around involving nested forms that can get kind of nasty, but it does work and (with a little extra work) will submit the parent form without trouble.

If you want, you can go drum up more support for the issue: GitHub Issue - dynamic element validation. Either way, here's the code:

http://jsfiddle.net/langdonx/6H8Xx/2/

HTML:

<div data-ng-app>
    <div data-ng-controller="MyController">
        <form id="my_form" name="my_form" action="/echo/jsonp/" method="get">
            <div data-ng-repeat="field in form.data.fields">
                <ng-form name="form">
                    <label for="{{ field.name }}">{{ field.label }}:</label>
                    <input type="text" id="{{ field.name }}" name="{{field.name}}" data-ng-model="field.data" required>
                    <div class="validation_error" data-ng-show="form['\{\{field.name\}\}'].$error.required">Can't be empty.</div>

                </ng-form>
            </div>
            <input type="submit" />
        </form>
    </div>
</div>

JavaScript:

MyController.$inject = ["$scope"];

function MyController($scope) {
    $scope.form = {};
    $scope.form.data = {};
    $scope.form.data.fields = []

    var f1 = {
        "name": "input_1",
        "label": "My Label 1",
        "data": ""
    };
    var f2 = {
        "name": "input_2",
        "label": "My Label 2",
        "data": ""
    };

    $scope.form.data.fields.push(f1);
    $scope.form.data.fields.push(f2);
}

这篇关于AngularJS:动态添加的字段未在 FormController 上注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 11:18