如何在 angularjs 中使用模板设置字段名 [英] how to set the fieldname using a template in angularjs
问题描述
我希望字段的标签与字段验证属性进行一些交互.我创建了一个工作示例的 plunker.
I want to have some interaction of the label for a field with the field validation properties. I created a plunker of a working example.
http://plnkr.co/edit/oNq5lmjtjRDaEkzKsrR2?p=preview
但在这个例子中,字段名是硬编码的.
But in this example the fieldname is hardcoded.
我尝试通过范围变量将字段名设置到模板中.这不起作用:
I tryed to set the fieldname via scope variable into the template. This is not working:
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:
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 中,字段名按预期分配.我该如何解决这个问题?
The fieldname in scope.$parent.myForm is '{{fieldName}}' instead of 'myField'. But in DOM the fieldname is assigned as expected. How can I solve this problem?
推荐答案
Stewie 是绝对正确的.如果创建了 ng-model 指令,它将立即在表单中注册.如果您查看 angular 源,您会发现 ngModel 是按其当前名称在数组 form
中注册的:
Stewie is absolutely right. If the ng-model directive is created it will immediately be registered at the form. If you have a look at the angular sources you will find that the ngModels are registered by their current name in the array form
:
if (control.$name) {
form[control.$name] = control;
}
就您而言,这是{{fieldName}}".这个name
不能改变,因为它是数组中的键.那么我们可以做些什么来改变这种情况呢?如果我们看一下 FormController API 我们可以看到有删除 ($removeControl
) 或添加 ($addControl
) 控件的函数.这两个函数都需要 NgModelController 作为输入参数.例如.angular 为我们的输入元素创建的 NgModelController.我们可以通过以下方式访问此控制器:
In your case this is '{{fieldName}}'. This name
can not be changed, because it is the key in the array. So what can we do to change this? If we have a look at the FormController API we can see there are functions to remove ($removeControl
) or add ($addControl
) controls. Both functions require the NgModelController as input parameter. E.g. the NgModelController that angular has created for our input element. We have access to this controller by:
var modelController = inputElement.controller('ngModel');
var modelController = inputElement.controller('ngModel');
我认为我们现在拥有了编写指令的所有信息:
I think we have now all information together to write the directive:
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条件:
I would also suggest publish the NgFormController to the directives scope. So you may write your css condition:
form[fieldName].$invalid
代替:
$parent.myForm[fieldName].$invalid
它更通用,因为您不需要知道表单的名称.
It is more generic, because you don't need to know the name of your form.
这篇关于如何在 angularjs 中使用模板设置字段名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!