Javascript 角度转置和范围

Javascript 角度转置和范围,javascript,angularjs,angularjs-directive,angularjs-scope,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,我正在尝试生成一个用于单击编辑输入字段的指令。因为我有各种不同类型的输入字段需要处理,所以我想让它成为一个属性类型指令,它只包含输入字段本身 然而,问题是,当在指令描述中使用scope参数时(对于ipDisable),事情会停止正常工作(请尝试在jsFiddle js部分的第44行中进行注释)。据推测,这是一个范围错误,但我真的不知道从哪里开始调试它,如果有任何帮助,我将不胜感激 jsFiddle: HTML: <input inplace type="string" ip-disabl

我正在尝试生成一个用于单击编辑输入字段的指令。因为我有各种不同类型的输入字段需要处理,所以我想让它成为一个属性类型指令,它只包含输入字段本身

然而,问题是,当在指令描述中使用scope参数时(对于ipDisable),事情会停止正常工作(请尝试在jsFiddle js部分的第44行中进行注释)。据推测,这是一个范围错误,但我真的不知道从哪里开始调试它,如果有任何帮助,我将不胜感激

jsFiddle:

HTML:

<input inplace type="string" ip-disable=false name="username" ng-model="uname">

JS:

myApp.directive('inplace',function($compile){
var compile=函数(远程通信、tAttrib、转置){
整个风险值=$('');
可编辑变量=$(“”+
''+
“<save>”);
append(可编辑).append({{ngModel.$viewValue}}+
''+
“<edit>”);
替换为(整体);
转移(远程通信、功能(克隆){
clone.removeAttr('inplace');
可编辑。前置(克隆);
});  
返回函数(范围、元素、属性){
var input_element=$($(element).find('input')[0]);
scope.name=input_element.name;
scope.ngModel=element.controller('ngModel');
scope.static=true;
scope.changeStatic=函数(){
if(范围静态){
scope.static=false;
}如果(!scope.ngModel.$error[scope.name]){
scope.static=true;
}
};
};
};
返回{
转移:'元素',
作用域:{disable:'&ipDisable'},
限制:“A”,
编译:编译
};  
});

这是因为您正在将
输入
元素移动到具有隔离作用域的元素内部,因此它无法再与其外部的作用域交互。因此,您绑定到的
uname
将不在输入的
ng模型
的范围内

您有两个选项—第一个选项根本不创建隔离作用域—您仍然可以通过链接函数中的
attrs
访问
ipDisable


另一个(更好的)解决方案是将
ngModel
添加到隔离作用域(
scope:{disable:'&ipDisable',ngModel:'='}
),并在输入发生更改时使用更新输入值。

Ed提出的解决方案解决了部分问题。然而,有一件事可能首先让我感到不快:

模板被编译到父范围中,而不是附加到新的指令范围中。为了解决这个问题,我需要在linker函数中手动编译创建的模板,在这里我可以将它绑定到适当的范围

工作解决办法是:

myApp.directive('inplace',function($compile){
var compile=函数(远程通信、tAttrib、转置){
整个风险值=$('');
可编辑变量=$(“”+
''+
“<save>”);
转移(远程通信、功能(克隆){
clone.removeAttr('inplace');
clone.attr('ng-model','model');
可编辑。前置(克隆);
});
append(可编辑).append({{model}}+
''+
“<edit>”);
返回函数(范围、元素、属性){
替换为($编译(全部)(范围));
scope.name=attrs.name;
scope.static=true;
scope.changeStatic=函数(){
if(范围静态){
scope.static=false;
}否则{
scope.static=true;
if(scope.name)scope.$emit('inplace-edit',scope.name);
}
};
};
};
返回{
转移:'元素',
作用域:{ipDisable:'&',模型:'='},
限制:“A”,
编译:编译
};  
});

(这可能对任何正在寻找类似东西并获得麻省理工学院许可证的人有用,也就是说,用它做你想做的事)。

我在myown上短暂地尝试了第一种可能性,但无法完全实现(我必须$watch有问题的属性,对吗?)。更好的解决方案听起来也相当复杂,除非我遗漏了什么。是否有一种相当简单的方法将整个指令ng模型直接绑定到输入字段ng模型,或者我必须手工连接所有API调用?
myApp.directive('inplace', function($compile) {

var compile = function(tElem,tAttrib,transclude) {

  var whole = $('<div ng-scope></div>');

  var editable = $('<div class="editable-transclude" ng-hide="static">'+
                  '<a ng-click="changeStatic()" ng-show="!static && !disable()">'+
                  '&ltsave&gt</a></div>');

  whole.append(editable).append('<span class="disabledText" ng-show="static">{{ngModel.$viewValue}}</span>' +
            '<a ng-click="changeStatic()" ng-show="static && !disable()">'+
            '&ltedit&gt</a>');

  tElem.replaceWith(whole);

  transclude(tElem,function(clone) {
    clone.removeAttr('inplace');
    editable.prepend(clone);
  });  

  return function(scope, element, attrs) {  

    var input_element = $($(element).find('input')[0]);
    scope.name = input_element.name;
    scope.ngModel = element.controller('ngModel');

    scope.static = true;

    scope.changeStatic = function() {
      if (scope.static) {
        scope.static = false;
      } else if (!scope.ngModel.$error[scope.name]){
        scope.static = true;
      }
    };
  };
};

return {
  transclude: 'element',
  scope: { disable: '&ipDisable' },
  restrict: 'A',
  compile: compile
};  
});
 myApp.directive('inplace', function($compile) {

var compile = function(tElem,tAttrib,transclude) {

  var whole = $('<div ng-scope></div>');

    var editable = $('<div class="editable-transclude" ng-hide="static">'+
                  '<a ng-click="changeStatic()" ng-show="!static && ipDisable()">'+
                  '&ltsave&gt</a></div>');

  transclude(tElem,function(clone) {
    clone.removeAttr('inplace');
    clone.attr('ng-model','model');
    editable.prepend(clone);
  });

  whole.append(editable).append('<span class="disabledText" ng-show="static">{{model}}</span>' +
            '<a ng-click="changeStatic()" ng-show="static && !ipDisable()">'+
            '&ltedit&gt</a>');


  return function(scope, element, attrs) {

    element.replaceWith($compile(whole)(scope));

    scope.name = attrs.name;

    scope.static = true;

    scope.changeStatic = function() {
      if (scope.static) {
        scope.static = false;
      } else {
        scope.static = true;
        if (scope.name) scope.$emit('inplace-edit',scope.name);
      }
    };
  };
};

return {
  transclude: 'element',
  scope: { ipDisable: '&', model: '=' },
  restrict: 'A',
  compile: compile
};  
});