Javascript ng模型在转置输入中的中断

Javascript ng模型在转置输入中的中断,javascript,angularjs,angularjs-directive,angularjs-scope,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,我正在编写一个非常简单的指令:它应该将一个输入元素包装在一个div中。问题在于,由于某种原因,它打破了ng模型。有关完整代码,请参阅此plunker: 如何使ng模型按预期运行 指令码 以下是指令的代码: testapp.directive('wrapInput', [function () { return { replace: true, transclude: 'element', template: '<div class="input-w

我正在编写一个非常简单的指令:它应该将一个输入元素包装在一个div中。问题在于,由于某种原因,它打破了ng模型。有关完整代码,请参阅此plunker:

如何使ng模型按预期运行

指令码 以下是指令的代码:

testapp.directive('wrapInput', [function () {
   return {
      replace: true,
      transclude: 'element',
      template: '<div class="input-wrapper" ng-transclude></div>'
   };
}]);
testapp.directive('wrapInput',[function(){
返回{
替换:正确,
转移:'元素',
模板:“”
};
}]);

如果将标记更改为如下所示

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

它很好用。我不知道为什么,但我以前在使用transclude:'element'和replace:true时见过这个问题。稍后我将不得不深入了解消息来源,看看发生了什么。无需考虑,此解决方案产生的标记应该是相同的。

我认为您必须为指令定义一个隔离范围,可能还有一个控制器。大概是这样的:

return {
  replace: true,
  transclude: 'element',
  scope: {},
  controller: function(scope){},
  template: '<div class="input-wrapper" ng-transclude></div>'
返回{
替换:正确,
转移:'元素',
作用域:{},
控制器:函数(作用域){},
模板:“”
})


然后,您只需将指令的范围绑定到父范围。不幸的是,我还不能让它在您的plnkr中运行,但我会在运行时编辑我的答案。

我想既然
ng repeat
可以做到这一点,那么它必须是可能的:

app.directive('wrapthishing',['$compile',函数($compile){
返回{
限制:“A”,
转移:'元素',
链接:函数(范围、元素、属性、ctrl、transclude){
//编译一个新的DOM上下文并将其绑定到我们的范围。
变量模板=角度元素(“”);
变量上下文=$compile(模板)(范围);
转置(功能(克隆、示波器){
//为了实现这一点,我们需要从中删除directive属性
//在将克隆编译回其原始作用域之前将其删除。如果
//如果不这样做,编译器将重新评估我们的指令,创建
//无限循环。
//我们可以使用$attr属性来确定属性的变化
//使用了(即数据包装这个东西,x包装这个东西,包装:这个东西,
//等等)。
//有关属性规范化的详细信息,请参见:
// http://www.bennadel.com/blog/2648-inspecting-attribute-normalization-within-directives-in-angularjs.htm
clone.removeAttr(attrs.$attr.wrapthishing);
//编译被转移的元素并将其绑定到自己的范围
//将它附加到我们的新上下文中。
append($compile(clone)(theScope));
});
元素。替换为(上下文);
}
};
}]);
return {
  replace: true,
  transclude: 'element',
  scope: {},
  controller: function(scope){},
  template: '<div class="input-wrapper" ng-transclude></div>'
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 );
    }
  };
}]);