手动创建节点和ng-model

时间:2013-11-04 05:21:08

标签: angularjs

在DRY bootstrap和AngularJS的更多尝试中,我试图在保持ng-model关系的同时创建表单和子项。我得到了正确的HTML输出,但是没有正确连接模型关系,并且模型没有更新:

Vanilla HTML

<form role="form" ng-model="customer">
  <div class="form-group">
    <label for="name">Your Name</label>
    <input id="name" class="form-control" ng-model="customer.name" />
  </div>
</form>

简化(目标)HTML

<div abs-form ng-model="customer">
  <input id="name" label="Full Name" placeholder="i.e. Joe Smith"/>
</div>

控制器

.controller('HomeCtrl', function($scope){
    $scope.customer = {};
}

abs-form指令

.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);

  }
}
})

这是上面指令的输出,就像我说的,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属性之外,还有更多内容,但Angular正在做一些注册连接的事情......?

1 个答案:

答案 0 :(得分:1)

您的指令存在的问题是它引入了一个不包含原始模型名称的隔离范围。因此,范围变量customer在指令的范围内以名称ngModel为人所知。

我更新了代码以摆脱jQuery依赖,但基本上它仍然做同样的事情。

看到这个小提琴:manual creation of nodes and ng-model