我想制作一个项目列表,双击一个项目使其可编辑。目前,在编辑项目时,单击外部(即blur
)或通过键盘输入会提交新值。
现在,我想添加一个+
图标,将项目添加到列表中。 点击+
图标后,我希望焦点(和双击)位于添加的项目上,以便我们可以直接修改。
有谁知道如何实现这个目标?
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<style>
input {
font-size: 20px;
border:none;
background-color:transparent;
}
</style>
</head>
<body ng-app="app" ng-controller="Ctrl">
<table>
<tr ng-repeat="item in items">
<td>
<input type="text" value="{{item.name}}" ng-blur='eEditable = -1' ng-readonly='$index !== eEditable' ng-dblclick="eEditable = $index" ng-keypress="keypress($event)"/>
</td>
</tr>
</table>
<div ng-click="add()">+</div>
<script>
var app = angular.module('app', []);
app.controller('Ctrl', ['$scope', function ($scope) {
$scope.items = [{ name: "item #1" }, { name: "item #2" }, { name: "item #3" }];
$scope.eEditable = -1;
$scope.keypress = function ($event) {
if ($event.keyCode === 13)
$event.target.blur()
}
$scope.add = function () {
$scope.items.push({name: "new"});
}
}])
</script>
</body>
</html>
答案 0 :(得分:1)
当我在角度方面遇到这样的问题时,有时候更容易使用jQuery。
$scope.add = function () {
$scope.items.push({name: "new"});
$scope.eEditable = $scope.items.length-1;
window.setTimeout(function() {
$("table tr:last td input").focus();
}, 0);
https://jsbin.com/yegokobuna/edit?html,output
我将jQuery代码推送到window.setTimeout(..., 0)
,以便在角度框架完成呈现HTML元素之后调用代码。
这不是一个很好的解决方案。维护起来比较困难,因为Controller代码现在需要对渲染的HTML有深入的了解。如果我要修改视图以显示一系列div
而不是表格行中的项目,那么我将不得不去改变控制器代码。
答案 1 :(得分:0)
这是使用自定义指令的解决方案。 (我保留了JQuery,因为它有两个有用的方法:focus
和select
)
app.directive("customFocus", function() {
return {
restrict : "A",
link: function(scope, element, attrs) {
scope.$watch(attrs.customFocus, function(newValue) {
if(newValue) {
$(element).focus();
window.setTimeout(function() { $(element).select(); }, 0);
}
});
}
}
现在,您可以将此指令作为属性应用于每个input
元素:
<input
type="text"
value="{{item.name}}"
custom-focus='$index == eEditable'
ng-blur='eEditable=-1'
ng-readonly='$index !== eEditable'
ng-dblclick="eEditable = $index"
ng-keypress="keypress($event)"/>
控制器中唯一需要的更改是在添加项目时将eEditable
设置为等于最终索引:
$scope.add = function () {
$scope.items.push({name: "new"});
$scope.eEditable = $scope.items.length-1;
}
https://plnkr.co/edit/3bkJa2FcbTm4uSZ95BNi?p=preview
此解决方案似乎比the pure JQuery solution更优雅,因为使用此解决方案,控制器无需了解呈现的DOM元素。
一个问题是它可以说谎:如果有多个元素带有“custom-focus ='true'”,那么你将会有关于哪个元素实际被授予焦点的未定义行为。< / p>