Javascript &引用;“角度方式”;从控制器触发contenteditable控件?
我有一个项目列表,当前(选定)项目在屏幕的不同部分显示得更详细。在更详细的部分中,您可以使用Javascript &引用;“角度方式”;从控制器触发contenteditable控件?,javascript,jquery,angularjs,contenteditable,Javascript,Jquery,Angularjs,Contenteditable,我有一个项目列表,当前(选定)项目在屏幕的不同部分显示得更详细。在更详细的部分中,您可以使用contenteditable编辑所选项目的部分 现在,当用户向列表中添加一个项目时,我想触发元素上的focus事件,以便用户可以立即编辑例如标题 我所拥有的一个非常简化的版本是: function ListCtrl($scope) { $scope.list = [ "one", "two" ]; $scope.add = function() { $scope.li
contenteditable
编辑所选项目的部分
现在,当用户向列表中添加一个项目时,我想触发元素上的focus
事件,以便用户可以立即编辑例如标题
我所拥有的一个非常简化的版本是:
function ListCtrl($scope) {
$scope.list = [
"one",
"two"
];
$scope.add = function() {
$scope.list.push("new item");
jQuery("li:last").trigger("focus");
};
}
在本例中使用jQuery
。使用angular.element
失败:
jqLite不支持通过选择器查找元素
在这一点上,我已经熟悉了足够的角度来考虑使用<代码> jQuery < /Cord>代码气味。它是这样写的:
解决问题时,首先“以角度思考”;如果你想不出一个解决方案,问问社区;如果在所有这些之后都没有简单的解决方案,那么请随意使用jQuery因此,我在这里问社区:有没有更好的方法可以让用户在不触发
焦点的情况下立即编辑元素,就像用户单击内容可编辑的元素一样?据我所知,没有更好/更短的方法可以让用户在不触发焦点的情况下立即编辑元素,因此,我将致力于改进您必须满足Angular应用程序设计原则的内容
根据“角度方式”,DOM操作必须发生在指令中,业务逻辑应该包含在控制器中
解决方案是“让指令和控制器对话”。你的例子应该是:
控制员:
function ListCtrl($scope) {
var count = 1;
$scope.list = [
"one",
"two"
];
$scope.add = function() {
$scope.list.push("new item " + count);
$scope.$broadcast("newItemAdded");
count++;
};
}
该指令:
function ListDirective($timeout) {
return {
link: function(scope, element, attr) {
scope.$on("newItemAdded", function() {
$timeout(function() {
var elements = element.find("li");
elements[elements.length - 1].focus();
});
});
}
};
}
jshiddle:谢谢。虽然这个额外的指令包含更多的代码,但看起来更符合“角度方式”。但有一个问题:为什么我需要将$scope.$broadcast()
调用包装到$timeout()
?超时
确保在ng repeat
渲染完成后广播消息,因为timeout
是在摘要周期结束时执行的,即在新项真正呈现并可由指令进行操作之后。再看一下,timeout
在指令的事件侦听器中比在控制器中更有意义,因为它与DOM相关。我将更新示例和JSFIDLE中的代码。