0

ブートストラップと AngularJS を DRY しようとする試みの中で、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>

同様のシナリオ(および同様の解決方法)で見つけたいくつかの質問

2 番目の質問は最良のシナリオでしたが、「顧客」モデルに貢献するための新しい入力を取得できないようです。ノードの属性を追加または変更するだけではng-modelなく、接続を登録するためにAngularが行っていることはあると思います...?

4

1 に答える 1

1

ディレクティブの問題は、元のモデル名を含まない分離スコープが導入されることです。スコープ変数は、以降、ディレクティブのスコープ内のcustomer名前で認識されます。ngModel

jQuery の依存関係を取り除くためにコードを更新しましたが、基本的には同じことを行います。

このフィドルを参照してください:ノードと ng-model の手動作成

于 2013-11-04T08:43:59.527 に答える