angularjs - 如何使用 angularjs 中的模板设置字段名

标签 angularjs angularjs-directive

我希望字段标签与字段验证属性进行一些交互。 我创建了一个工作示例的 plunker。

http://plnkr.co/edit/oNq5lmjtjRDaEkzKsrR2?p=preview

但在此示例中,字段名称是硬编码的。

我尝试通过范围变量将字段名称设置到模板中。这不起作用:

http://plnkr.co/edit/yEl04xyFR5RWYCmI2bMH?p=preview

HTML:

<form name="myForm" ng-controller="ctrl">
  <fieldset field-name="{{model.fieldName}}" label-text="{{model.label}}" ng-model="model.value">
  <fieldset>
</form>

JavaScript:

var app = angular.module('myApp',[]);
app.directive('fieldset', function(){
  return {
    template: '<label ng-class="{invalid:$parent.myForm[{{fieldName}}].$invalid}">{{lbl}}</label>: ' +
              '<input name="{{fieldName}}" ng-model="value" required>',
    restrict : 'E',
    scope : {
              value : '=ngModel',
              lbl : '@labelText',
              fieldName : '@'
            },

    link : function(scope, elem, attrs) {
      console.log(scope.$parent.myForm);
    }        
  }
})

app.controller('ctrl', function($scope) {
  $scope.model = {
    fieldName : 'myField',
    label : 'Label for Field',
    value : 6
  } 
});

scope.$parent.myForm 中的字段名称是“{{fieldName}}”而不是“myField”。但在 DOM 中,字段名是按预期分配的。 我该如何解决这个问题?

最佳答案

Stewie 是绝对正确的。如果创建了 ng-model 指令,它将立即在表单中注册。如果您查看 Angular 源,您会发现 ngModel 是按其当前名称在数组 form 中注册的:

if (control.$name) {
  form[control.$name] = control;
}

在您的例子中,这是“{{fieldName}}”。这个name无法更改,因为它是数组中的键。那么我们可以做些什么来改变这一点呢?如果我们看一下 FormController API 我们可以看到有删除($removeControl)或添加($addControl)控件的函数。这两个函数都需要 NgModelController 作为输入参数。例如。 Angular 为我们的输入元素创建的 NgModelController。我们可以通过以下方式访问该 Controller :

var modelController = inputElement.controller('ngModel');

我认为我们现在已经掌握了编写指令的所有信息:

app.directive('fieldset', function(){
  return {
    template: '<label ng-class="{invalid:form[fieldName].$invalid}">{{lbl}}</label>: ' +
              '<input name="{{fieldName}}" ng-model="value" required>',
    restrict : 'E',
    require: '^form', // we need the parent NgFormController 
    scope : {
              value : '=ngModel',
              lbl : '@labelText',
              fieldName : '@'
         },

    link : function(scope, elem, attrs, formCtrl) {
       // get the NgModelController for the input element
       var modelCtrl = elem.find('input').controller('ngModel');

       // remove the ModelController from the FormController
       formCtrl.$removeControl(modelCtrl); 
       // set the right name
       modelCtrl.$name = scope.fieldName; 
       // add the namend ModelController to the FormController
       formCtrl.$addControl(modelCtrl); 

       // publish the FormController to the scope - so we don't need to mess around with the parent scope.
       scope.form = formCtrl;
    }
  }
})

我还建议将 NgFormController 发布到指令范围。所以你可以写你的CSS条件:

form[fieldName].$invalid

代替:

$parent.myForm[fieldName].$invalid

它更通用,因为您不需要知道表单的名称。

PLUNKR

关于angularjs - 如何使用 angularjs 中的模板设置字段名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21201087/

相关文章:

angularjs - 使用 AngularJS 在一页上使用多个 4.2 CKEditor 实例

android - 如何从 AngularJS 中的 ng-repeat 获取值

javascript - 获取 AngularJS 应用程序中的所有范围

javascript - Angular Directive(指令)更新多个元素的高度以匹配最高的元素

javascript - Angular 指令中的数据困惑

jquery - 全日历重新获取事件回调

javascript - 如何更改相同的 ng-repeat 值并仅显示选择值

javascript - AngularJS - 指令在模型更新后不触发

javascript - 调用与 Angular 指令绑定(bind)的参数化函数

angularJS 指令不会立即支持 ng-show/ng-hide