转换输入中的ng-model中断

时间:2013-10-16 19:07:48

标签: javascript angularjs angularjs-directive angularjs-scope

我正在编写一个非常简单的指令:它应该在div中包含一个输入元素。我为此使用了翻译。问题在于它出于某种原因打破了ng-model。有关完整代码,请参阅此plunker:http://plnkr.co/edit/tYTsVUbleZV1iG6eMgjo

如何使ng-model按预期运行?

指令代码

这是指令的代码:

testapp.directive('wrapInput', [function () {
   return {
      replace: true,
      transclude: 'element',
      template: '<div class="input-wrapper" ng-transclude></div>'
   };
}]);

3 个答案:

答案 0 :(得分:3)

如果您将标记更改为

<div  wrap-input>
  <input type="text" ng-model="anObject.anotherValue"/>
</div>

然后你也可以使用

transclude: true // instead of transclude: 'element'

它运作得很好。我不能说为什么,但在使用transclude之前我已经看过这个问题:'element'和replace:true。我将不得不深入了解源代码,看看发生了什么。 Reagrdless,这个解决方法的结果标记应该是相同的。

答案 1 :(得分:3)

我认为,因为ng-repeat可以做到,所以必须

http://plnkr.co/edit/stf02iPNvNnlsx1dsFZx?p=preview

app.directive( 'wrapThisThing', [ '$compile', function( $compile ) {
  return {
    restrict: 'A',
    transclude: 'element',
    link: function( scope, element, attrs, ctrl, transclude ) {

      // Compile a new DOM context and bind it to our scope.
      var template = angular.element( '<div class="wrap">' );
      var context = $compile( template )( scope );

      transclude( function( clone, theScope ) {
        // To make this work, we need to remove our directive attribute from
        // the clone before compiling it back to its original scope. If we
        // don't do this, the compiler will re-evaluate our directive, creating
        // an infinite loop.

        // We can use the $attr property to figure out what attribute variation
        // was used (ie. data-wrap-this-thing, x-wrap-this-thing, wrap:this:thing,
        // etc.).
        // See more about attribute normalization:
        // http://www.bennadel.com/blog/2648-inspecting-attribute-normalization-within-directives-in-angularjs.htm

        clone.removeAttr( attrs.$attr.wrapThisThing );

        // Compile the transcluded element and bind it to its own scope. Then
        // append it to our new context.
        context.append( $compile( clone )( theScope ) );
      });
      element.replaceWith( context );
    }
  };
}]);

答案 2 :(得分:0)

我相信你必须为你的指令定义一个隔离范围和控制器。像这样:

return {
  replace: true,
  transclude: 'element',
  scope: {},
  controller: function(scope){},
  template: '<div class="input-wrapper" ng-transclude></div>'

};

然后,您只需将指令的范围绑定到父范围即可。不幸的是,我还不能在你的plnkr中使用它,但是当我这样做时我会编辑我的答案。