Forms 是否可以基于Angularjs中的模型数据在指令中添加角度化html标记和属性?
我想构建一个指令,该指令将基于设置的嵌套对象构建表单输入,这些设置包括输入类型、要绑定的模型和html属性。我一直在敲打我的头,也许,我即将得出结论,这是Angular没有能力做的事情。我想构建一个指令,它可以接受如下对象数组:Forms 是否可以基于Angularjs中的模型数据在指令中添加角度化html标记和属性?,forms,angularjs,Forms,Angularjs,我想构建一个指令,该指令将基于设置的嵌套对象构建表单输入,这些设置包括输入类型、要绑定的模型和html属性。我一直在敲打我的头,也许,我即将得出结论,这是Angular没有能力做的事情。我想构建一个指令,它可以接受如下对象数组: [{ "label":"When did it happen", "model": $scope.event.date, "element":"input", "type": "date", "options":{
[{
"label":"When did it happen",
"model": $scope.event.date,
"element":"input",
"type": "date",
"options":{
"class":"big",
"required": true,
},
},{
"label":"How did it happen?",
"model": $scope.event.cause,
"element":"textarea",
"options":{
"cols":45,
"rows":55,
},
},{
"label":"How many times did it happen?",
"model": $scope.event.times,
"element":"input",
"options":{},
}],
我在指令的许多不同方面都遇到了困难。我不断遇到一些问题
- 模板和控制器指令函数都不能访问任何类型的作用域,这些作用域可以访问任何类型的数据,尤其是我制作的数组。这意味着我要等到以后才能决定如何构建DOM(即标记类型和属性)
- 所有编译都是在链接函数之前完成的。我能够在链接函数中操作DOM,但没有一个是角度化的。这意味着,如果我添加一个必需的属性,angular的ngValidate就不会知道它。如果我尝试更改标记类型,我会重置并丢失模型绑定等
看起来这就是angular跑步的方式。如果不具体指定所有内容,是否没有好的方法可以影响基于模型数据的DOM标记类型和属性?这样的方法如何:
$scope.event = {
date: new Date(),
cause:'It was the colonel in the kitchen with the revolver',
time:5, //...
$metadata: data
};
其中data
这里只是您已经显示的数组。(除了model属性,它只是一个表示事件属性的字符串,如下所示:
{
"label":"When did it happen",
"model":'date',
"element":"input",
"type": "date",
"options":{
"class":"big",
"required": true,
}
}
然后,您的指令只需访问父作用域上给定的属性。(event
)并将元数据处理为可用的模板,然后就可以对其进行编译
这是这样一个指令,指令
myApp.directive('contentForm',function($compile,$interpolate){
var template = "<span class='lbl'>{{label}}</span><{{element ||'input'}} {{options}}"+
" ng-model='{{root+'.'+model}}'></{{element}}>";
function linkerFunction(scope,element,attrs){
if(!scope[attrs.contentForm])return;
var metadata = scope[attrs.contentForm].$metadata || false;
if(!metadata)return;
element.html(getHtml(metadata,attrs.contentForm));
$compile(element.contents())(scope);
}
return {
restrict: 'A',
replace: true,
link:linkerFunction
};
//interpolate the template with each set of metadata
function getHtml(metadata,root){
var interpolation = $interpolate(template);
var html = '';
if(angular.isArray(metadata)){
for(var i = 0; i < metadata.length; i++){
metadata[i].root = root;
metadata[i].options = processOptions(metadata[i].options);
html += interpolation(metadata[i]) + '</br>'
}
}else{
html = interpolation(metadata);
metadata.options = processOptions(metadata.options);
}
return html;
}
// parse object into html attributes
function processOptions(options){
var result = '';
for(var key in options){
if(options.hasOwnProperty(key)){
result += ' '+key+"='"+options[key]+"'"
}
}
return result.trim();
}
});
myApp.directive('contentForm',function($compile,$interpolate){
var template=“{label}}”;
函数链接函数(作用域、元素、属性){
如果(!scope[attrs.contentForm])返回;
var metadata=scope[attrs.contentForm]。$metadata | | false;
如果(!元数据)返回;
html(getHtml(元数据,attrs.contentForm));
$compile(element.contents())(范围);
}
返回{
限制:“A”,
替换:正确,
link:linkerFunction
};
//使用每组元数据插入模板
函数getHtml(元数据,根){
var插值=$interpolate(模板);
var html='';
if(angular.isArray(元数据)){
for(var i=0;i'
}
}否则{
html=插值(元数据);
metadata.options=processOptions(metadata.options);
}
返回html;
}
//将对象解析为html属性
函数processOptions(选项){
var结果=“”;
for(变量输入选项){
if(options.hasOwnProperty(键)){
结果+=''+键+'=''+选项[键]+''
}
}
返回result.trim();
}
});
你可能想更改模板。我似乎忘记输入一个类型。但这应该是相当直接的。我希望这会有帮助!这太不可思议了。你就是Caleb。在你来帮助我之前,我在这方面花了太多时间。我学到了很多。非常感谢。