Angularjs 手动创建节点和ng模型

Angularjs 手动创建节点和ng模型,angularjs,Angularjs,在更多干燥引导和AngularJS的尝试中,我尝试在维护ng模型关系的同时创建一个表单和子对象。我获得了正确的HTML输出,但某些内容与模型关系连接不正确,并且模型未被更新: 香草HTML abs表格指令 指令('absForm',函数($compile){ 变量输入=$(''), 标签=$(''); 组=$(''), formElements=[]; 返回{ 限制:“EA”, 替换:正确, 排除:错误, 范围:{ ngModel:“=”, 标签:“@” }, 编译:函数(远程通讯、tAttrs

在更多干燥引导和AngularJS的尝试中,我尝试在维护
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>