Angularjs 手动创建节点和ng模型
在更多干燥引导和AngularJS的尝试中,我尝试在维护Angularjs 手动创建节点和ng模型,angularjs,Angularjs,在更多干燥引导和AngularJS的尝试中,我尝试在维护ng模型关系的同时创建一个表单和子对象。我获得了正确的HTML输出,但某些内容与模型关系连接不正确,并且模型未被更新: 香草HTML abs表格指令 指令('absForm',函数($compile){ 变量输入=$(''), 标签=$(''); 组=$(''), formElements=[]; 返回{ 限制:“EA”, 替换:正确, 排除:错误, 范围:{ ngModel:“=”, 标签:“@” }, 编译:函数(远程通讯、tAttrs
ng模型
关系的同时创建一个表单和子对象。我获得了正确的HTML输出,但某些内容与模型关系连接不正确,并且模型未被更新:
香草HTML
abs表格指令
指令('absForm',函数($compile){
变量输入=$(''),
标签=$('');
组=$(''),
formElements=[];
返回{
限制:“EA”,
替换:正确,
排除:错误,
范围:{
ngModel:“=”,
标签:“@”
},
编译:函数(远程通讯、tAttrs){
var children=tElement.children();
var tplement=角度元素(“”);
//从元素中清除HTML
html(“”);
//循环遍历模板节点中的每个子节点并创建
//一个新的输入,克隆属性
angular.forEach(子对象,函数(子对象){
var newInput=input.clone(),
newLabel=label.clone(),
newGroup=group.clone(),
$child=$(child),
属性=child.attributes;
//添加“for”属性和标签文本
newLabel.attr('for',$child.attr('id'));
newLabel.text($child.attr('label'));
//将类添加到输入中
newInput.addClass('form-control');
newInput.attr('ng-model',tAttrs.ngModel++“++$child.attr('id'));
//将属性从原始节点复制到新节点
$.each(属性、函数(索引、属性){
newInput.attr(prop.name、prop.value);
})
//存储表单元素以供以后在link()中使用
formElements.push(新标签、新输入)
//由于某种原因,传入formElements会使附加操作变得一团糟
append([newLabel,newInput]);
//将组附加到元素
tplement.append(新组)
})
//$('input',tplement).wrap('')
//最后,用我们的tplement替换它
远程通信。替换为(tplement);
}
}
})
这是上面指令的输出,正如我所说的,HTML很好(据我所知),但是模型没有连接:
<form role="form" ng-model="customer" class="ng-pristine ng-valid">
<div class="form-group">
<label for="name">Full Name</label>
<input class="form-control ng-pristine ng-valid" ng-model="customer.name" id="name" label="Full Name" placeholder="i.e. Joe Smith">
</div>
</form>
全名
我在类似场景中发现的一些问题(以及类似的解决方法)
第二个问题是最佳方案,但我似乎无法让我的新输入为“客户”模型做出贡献。我认为这不仅仅是在节点上添加或更改
ng model
属性,而是在注册连接方面做了一些事情…?您的指令的问题在于它引入了一个不包括原始模型名称的隔离范围。此后,范围变量customer
在指令的范围内被称为ngModel
我更新了代码以摆脱jQuery依赖关系,但基本上它仍然做同样的事情
查看此提琴:不确定
ng模型
在表单标签上有什么好处……但表单确实需要name
如果您希望将其发布到范围并使用验证,我总是使用与用于输入的ng模型
对象无关的任意名称创建表单。然后使用表单名称进行验证,例如提交按钮上的ng disabled=“formName.$invalid”
,我会把它放在口袋里,因为这并不能解决问题,但是一种很好的做法。表单标记上的ng model
为子节点提供了一个位置,让它们知道它们所附加的模型,从编译函数解析模型的名称,并附加[inputId]
,也就是说,customer.name
。从未使用过它,因为ng model
在输入时会根据文档自动向scope对象注册,它们也会绑定到formName对象中。ngModel
的文档只讨论输入/文本区域/选择等,而不是表单本身,因为我很好奇。这是否可能是您关于在表单标签上注册它的假设?如果有更简单的方法来揭露事情的话,我是完全开放的……但我还没有弄清楚它是如何做到的;它已经被使用了。而且在表单上没有关于它的文档,看起来很可靠,范围有时是一个棘手的问题。我回家后会多做些测试,让你知道!谢谢那就行了!这么小的变化,万分感谢!
<div abs-form ng-model="customer">
<input id="name" label="Full Name" placeholder="i.e. Joe Smith"/>
</div>
.controller('HomeCtrl', function($scope){
$scope.customer = {};
}
.directive('absForm', function($compile){
var input = $('<input />'),
label = $('<label />');
group = $('<div class="form-group"></div>'),
formElements = [];
return {
restrict : 'EA',
replace : true,
transclude : false,
scope : {
ngModel : '=',
label : "@"
},
compile : function(tElement, tAttrs){
var children = tElement.children();
var tplElement = angular.element('<form role="form" ng-model="'+ tAttrs.ngModel +'" />');
// Clear the HTML from our element
tElement.html('');
// Loop through each child in the template node and create
// a new input, cloning attributes
angular.forEach(children, function(child){
var newInput = input.clone(),
newLabel = label.clone(),
newGroup = group.clone(),
$child = $(child),
attributes = child.attributes;
// Add the "for" attribute and the label text
newLabel.attr('for', $child.attr('id'));
newLabel.text($child.attr('label'));
// Add the class to the input
newInput.addClass('form-control');
newInput.attr('ng-model', tAttrs.ngModel + "." + $child.attr('id'));
// Copy the attributes from the original node to the new one
$.each(attributes, function(index, prop){
newInput.attr(prop.name, prop.value);
})
// Store the form elements for use in link() later
formElements.push(newLabel, newInput)
// Some reason passing in the formElements botches the appending
newGroup.append([newLabel, newInput]);
// Append the group to the element
tplElement.append(newGroup)
})
//$('input', tplElement).wrap('<span>')
// finally, replace it with our tplElement
tElement.replaceWith(tplElement);
}
}
})
<form role="form" ng-model="customer" class="ng-pristine ng-valid">
<div class="form-group">
<label for="name">Full Name</label>
<input class="form-control ng-pristine ng-valid" ng-model="customer.name" id="name" label="Full Name" placeholder="i.e. Joe Smith">
</div>
</form>