角度转换和范围

时间:2014-03-24 14:11:46

标签: javascript angularjs angularjs-directive angularjs-scope

我正在尝试为点击编辑输入字段生成指令。由于我需要使用各种不同类型的输入字段,我想让它成为一个属性类型指令,它只是转换输入字段本身。

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

的jsfiddle: http://jsfiddle.net/HbYwX/3/

HTML:

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

JS:

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
};  
});

2 个答案:

答案 0 :(得分:1)

这是因为您将input元素移动到具有隔离范围的元素内部,因此它不再与其外部的范围进行交互。因此,您绑定的uname与您输入ng-model的范围不同。

您有几个选项 - 首先不是要创建隔离范围 - 您仍然可以通过链接功能中的ipDisable访问attrs

另一个(更好的)解决方案是将ngModel添加到隔离范围(scope: { disable: '&ipDisable', ngModel:'='},),并使用ngModelController自行更新输入的值,输入已更改。

答案 1 :(得分:1)

Ed提出的解决方案解决了部分问题。然而,还有一个可能首先让我失望的是:

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

工作解决方案是: http://jsfiddle.net/HbYwX/5/

 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
};  
});

(这可能对任何寻找类似东西并且在MIT许可下的人都有用,即按照你的意愿行事。)