1

我正在尝试设置一个输入

<form name="myForm">
    <input name="{{ name }}"/>
</form>

它在dom中工作。我懂了

<input name="whatever_name_is_set_to"/>

但是在我的 ngForm 我有

$scope.myForm:  { 
    {{ name }}:  {  } 
} 

多哈

我为什么要这样做?我正在尝试创建一个指令,以便我可以以编程方式构建我的表单。然后我可以做类似的事情

<div my-field
        name="credits"
        field="course.credits"
        field-options="courseOptions.credits"
        title="Credits"
></div>

普朗克

4

2 回答 2

2

2017 年 3 月 23 日更新:

对于 AngularJS >= 1.3 ,输入名称现在支持插值


2014-06-05 的原始答案(对于 AngularJS <= 1.2 正确):

我昨天刚刚回答了一个关于动态命名表单元素的类似问题。简而言之,不,您不能使用插值来动态命名表单字段 - 正如您所见,插值字符串最终会出现在字段名称中。

在您的情况下,您可能需要研究在myField指令中动态编译输入 HTML。

$compile这是一个用于动态生成表单元素的简化示例:http: //jsfiddle.net/Sly_cardinal/XKYJ3/

HTML:

<div ng-app="myApp">
    <form name="myForm" ng-controller="myController">
        <div my-field 
             name="courseName"
             field="course.courseName"
             title="Course Name"></div>
        
        <div my-field 
             name="credits"
             field="course.credits"
             title="Credits"></div>
        
        <!-- Show that the values are bound. -->
        <pre>course: {{course | json:'  '}}</pre>
        <!-- Show that the field is being registered with the ngFormController. -->
        <pre>myForm.credits.$dirty: {{myForm.credits.$dirty}}</pre>
    </form>
</div>

JavaScript:

angular.module('myApp', [])
.controller('myController', ['$scope', function($scope){
    $scope.course = {
        credits: 100,
        courseName: 'Programming 201'
    };
}])
.directive('myField', ['$compile', '$parse', function($compile, $parse){
    // In a real project you'd probably want to use '$templateCache' instead
    // of having strings in your code.
    var tmpl = $compile('<label>{{title}}</label>');
    
    return {
        scope: true,
        link: function(scope, element, attr){
            scope.title = attr.title;
            
            var newEl = angular.element('<input type="text"/>');
            newEl.attr('ng-model', attr.field);
            newEl.attr('name', attr.name);
            
            tmpl(scope, function(fieldEl, scope){
                $compile(newEl[0].outerHTML)(scope, function(el, scope){
                    fieldEl.append(el);
                    element.append(fieldEl);
                });
            });
        }
    }
}]);

关于此示例的注释:

这是一个非常特殊的情况——生成动态表单元素——需要使用$compile. 这不是处理 Angular 输入和表单时的“首选”解决方案——Angular 将处理所有常见情况,包括指令、数据绑定和框架提供的所有其他内容。另外,正如 Marc Kline 的评论所显示的,Angular 似乎会在未来的某个时候自己处理动态表单管理。

如果您要继续使用$compile生成这些表单元素的路径,那么您可能希望使用$templateCache来管理您的模板,这样您就不会尝试在指令中管理模板字符串。

于 2014-06-05T23:18:46.857 回答
0

老问题,但如果有人正在寻找一种方法来解决所问的问题,您可以创建一个指令,在$compile'ing 之后动态创建元素的名称。

@Sly_cardinal 发布的答案的更新版本在这里:http: //jsfiddle.net/XKYJ3/1/

HTML

<div ng-app="myApp">
    <form name="myForm" ng-controller="myController">
        <label for="{{ course.courseName.name }}" ng-bind="course.courseName.title"></label>
        <input id="{{ course.courseName.name }}" dynamic-input-name="course.courseName.name" ng-model="course.courseName.value" type="text" required />
        <br />
        <label for="{{ course.credits.name }}" ng-bind="course.credits.title"></label>
        <input id="{{ course.credits.name }}" dynamic-input-name="course.credits.name" ng-model="course.credits.value" type="number" required />

        <!-- Show that the values are bound. -->
        <pre>course: {{course | json:'  '}}</pre>
        <!-- Show that the field is being registered with the ngFormController. -->
        <pre>myForm.credits_field.$dirty: {{ myForm.credits_field.$dirty }}</pre>
    </form>
</div>

Javascript

angular.module('myApp', [])
.controller('myController', ['$scope', function($scope){
    $scope.course = {
        credits: {
            title: 'Credits',
            value: 100,
            name: 'credits_field'
        },
        courseName: {
            title: 'Course name',
            value: 'Programming 201',
            name: 'course_name_field'
        }
    };
}])
.directive('dynamicInputName', ['$compile', '$parse', function($compile, $parse){
    return {
        restrict: 'A',
        terminal: true,
        priority: 100000,
        link: function(scope, elem) {
            var name = $parse(elem.attr('dynamic-input-name'))(scope);
            elem.removeAttr('dynamic-input-name');
            elem.attr('name', name);
            $compile(elem)(scope);
        }
    };
}]);
于 2016-11-11T04:06:10.833 回答