0

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

原版 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 正在做一些事情来注册连接......?

4

1 回答 1

1

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

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

请参阅此小提琴:手动创建节点和 ng-model

于 2013-11-04T08:43:59.527 回答