如何创建一个角度指令,在表单中添加输入,但也可以使用表单验证。
例如,以下指令创建了一个文本输入:
var template = '\
<div class="control-group" ng-class="{ \'error\': {{formName}}[\'{{fieldName}}\'].$invalid}">\
<label for="{{formName}}-{{fieldName}} class="control-label">{{label}}</label>\
<div class="controls">\
<input id="{{formName}}-{{fieldName}}" name="{{fieldName}}" type="text" ng-model="model" />\
</div>\
</div>\
';
angular
.module('common')
.directive('formTextField', ['$compile', function ($compile) {
return {
replace: true,
restrict: 'E',
scope: {
model: '=iwModel',
formName: '@iwFormName',
fieldName: '@iwFieldName',
label: '@iwLabel'
},
transclude: false,
template: template
};
}])
;
但是输入未添加到表单变量($ scope.formName)。我已经能够通过使用以下stackoverflow问题Angularjs: form validation and input directive中的dynamicName指令来解决这个问题,但是ng-class仍然无法工作。
更新
它现在似乎正在工作,但感觉就像一个黑客。我认为我需要范围来获取表单和字段名称,但是我可以直接从属性中读取它。这样做会在控制器范围形式变量中显示该字段。但是ng-class属性不适用。解决这个问题的唯一方法是在范围可用后再次添加html元素。
jsFiddle here
var template = '\
<div class="control-group">\
<label class="control-label"></label>\
<div class="controls">\
<input class="input-xlarge" type="text" />\
</div>\
</div>\
';
angular
.module('common')
.directive('formTextField', ['$compile', function ($compile) {
return {
replace: true,
restrict: 'E',
scope: false,
compile: function compile(tElement, tAttrs, transclude) {
var elem = $(template);
var formName = tAttrs.iwFormName;
var fieldName = tAttrs.iwFieldName;
var label = tAttrs.iwLabel;
var model = tAttrs.iwModel;
elem.attr('ng-class', '{ \'error\': ' + formName + '[\'' + fieldName + '\'].$invalid }');
elem.find('label').attr('for', formName + '-' + fieldName);
elem.find('label').html(label);
elem.find('input').attr('id', formName + '-' + fieldName);
elem.find('input').attr('name', fieldName);
elem.find('input').attr('ng-model', model);
// This one is required so that angular adds the input to the controllers form scope variable
tElement.replaceWith(elem);
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
// This one is required for ng-class to apply correctly
elem.replaceWith($compile(elem)(scope));
}
};
}
};
}])
;
答案 0 :(得分:1)
当我做这样的事情时,我使用指令compile
函数来构建我的html,然后再进行处理。例如:
myApp.directive('specialInput', ['$compile', function($compile){
return {
// create child scope for control
scope: true,
compile: function(elem, attrs) {
// use this area to build your desired dom object tree using angular.element (eg:)
var input = angular.element('<input/>');
// Once you have built and setup your html, replace the provided directive element
elem.replaceWith(input);
// Also note, that if you need the regular link function,
// you can return one from here like so (although optional)
return function(scope, elem, attrs) {
// do link function stuff here
};
}
};
}]);