我有一个名为contentEditable
的指令,该指令也引用了html5 attr
::docs::。
<p contentEditable="{{edit}}" ng-model="pages.title">default</p>
关于dblclick的指令,我希望contentEditable的值切换到true
; on blur切换到false
..
我一直在试验,双击拒绝正常工作。 不确定如何使这种行为符合我的要求。
var app = angular.module('morningharwoodApp');
app.directive('contenteditable', function() {
return {
require: 'ngModel',
scope: {
edit: '@'
},
controller: function($scope) {
$scope.edit = false;
console.log($scope.edit);
},
link: function(scope, elm, attrs, ctrl) {
// view -> model
elm.bind('blur', function() {
scope.$digest(function() {
ctrl.$setViewValue(elm.html());
});
});
// model -> view
ctrl.render = function(value) {
elm.html(value);
};
// load init value from DOM
ctrl.$setViewValue(elm.html());
elm.bind('dblclick', function(event) {
scope.edit = !scope.edit;
console.log(scope.edit);
console.log('keydown ' + event.which);
var esc = event.which === 27,
enter = event.which === 13,
el = event.target;
if (esc || enter) {
// console.log('esc');
ctrl.$setViewValue(elm.html());
scope.editable = false;
el.blur();
event.preventDefault();
}
});
}
};
});
答案 0 :(得分:4)
您正在错误地使用范围绑定,隔离范围绑定用于绑定指令范围和父控制器范围之间的值,而不是属性本身。
原始代码的结果是标记将始终存在且没有这样的值:
<div contenteditable ng-model="fName"> ..
为什么元素总是可编辑的。
如果要更改属性的值,可以改用attrs.$set()
。启用contenteditable
后,您必须手动关注元素,否则需要再次单击才能进入编辑模式。
elm.bind('dblclick', function () {
if (!attrs.contenteditable) {
attrs.$set('contenteditable', true);
elm[0].focus();
}
});
然后在模糊时重置属性:
elm.bind('blur', function () {
attrs.$set('contenteditable', false);
scope.$apply(function () {
ctrl.$setViewValue(elm.html());
});
});
您的ENTER/ESC
密钥逻辑也应该在keyup
事件
elm.bind('keyup', function (event) {
var esc = event.which === 27,
enter = event.which === 13;
if (esc || enter) {
event.preventDefault();
elm[0].blur();
}
});
请参阅下面编辑过的jsfiddle以获取完整的工作示例。
JSFiddle: http://jsfiddle.net/hMrTA/1/
答案 1 :(得分:0)
即使单击也可以编辑输入这一事实是因为您使用焦点元选择器来突出显示它。您可以通过单击(包括双击)和点击键盘上的Tab来实现焦点状态,直到它被选中,我认为这比您想要的更多。
我建议重新考虑你的指示。一个想法是有2个字段:一个标签(显示当前值)和一个输入字段(允许编辑),并根据您正在使用的标志仅显示一个。在标签上绑定dblclick事件以更改标志(并显示输入)并在输入上绑定blur事件以将其切换回来。