我正在尝试为点击编辑输入字段生成指令。由于我需要使用各种不同类型的输入字段,我想让它成为一个属性类型指令,它只是转换输入字段本身。
然而,问题是当使用范围参数到指令描述(对于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()">'+
'<save></a></div>');
whole.append(editable).append('<span class="disabledText" ng-show="static">{{ngModel.$viewValue}}</span>' +
'<a ng-click="changeStatic()" ng-show="static && !disable()">'+
'<edit></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
};
});
答案 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()">'+
'<save></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()">'+
'<edit></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许可下的人都有用,即按照你的意愿行事。)