将angularjs输入指令名称设置为变量

时间:2014-06-05 22:46:21

标签: angularjs angularjs-directive angularjs-ng-form

我正在设置像

这样的输入
<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>

Plunker

2 个答案:

答案 0 :(得分:2)

2017-03-23更新:

对于AngularJS&gt; = 1.3 interpolation is now supported in input names


2014-06-05的原始答案(AngularJS&lt; = 1.2更正):

我昨天刚刚回答了一个类似的问题about dynamically named form elements。简而言之,不,您不能使用插值动态命名表单字段 - 插值字符串将以您看到的字段名称结尾。

在您的情况下,您可能需要考虑动态编译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来管理模板,这样您就不会尝试管理模板字符串在你的指令里面。

答案 1 :(得分:0)

老问题,但是如果有人正在寻找一种方法来处理问题,你可以创建一个指令,在$compile之后动态创建元素的名称。

@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);
        }
    };
}]);