在开发时,我遇到了两次发射模糊的问题,当我只需要发射一次时。
ng-blur和ng-enter最终操作都是向数据库提出请求,在我们的情况下,只需要1个或从ng-blur或ng-enter中完成了2个请求。问题在于,NG-Enter行为导致对元素失去关注,该元素与NG-Blur有关。
这是我的两个问题:
-
是否有一种方法可以防止Angularjs在tododiv上发射ng-blur何时执行NG-Enter?
-
如果没有第一个问题的解决方案,我真的希望那里是,那我有什么选择?
下面您可以看到负责我问题的代码部分。
template.html
<div ng-repeat="todo in todos" ng-enter="stopEditTodo($index, $event, todo);" ng-dblclick="editTodo($event);">
<div class="card-details">
<div class="card-content">
<span ng-blur="stopEditTodo($index, $event, todo);">
{{todo.title}}
</span>
</div>
</div>
</div>
controller.js
app.controller('homeController', function($scope, Todos, $state){
$scope.editTodo = function($event) {
var text = angular.element(angular.element(event.currentTarget).find('span')[0]);
$event.preventDefault();
text.attr("contenteditable", "true");
}
$scope.stopEditTodo = function($index, $event, todo) {
angular.element(event.currentTarget).removeAttr('contenteditable');
}
});
指令.js
app.directive('ngEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if(event.which === 13) {
scope.$apply(function (){
scope.$eval(attrs.ngEnter);
});
event.preventDefault();
}
});
};
});
感谢您的时间!
由于ng-blur
触发了$evalAsync
,因此您在ng-enter
中实际上没有任何事情可以阻止它发生。
另一方面,您有一些选择:
选项#1-检查stopEditTodo
射击时是否仍可以编辑
是否可以编辑 var target = angular.element(event.target);
if (target.attr('contenteditable')) {
target.removeAttr('contenteditable');
// fire request
}
请注意,所有这些都可以通过完全自定义的指令来封装直接DOM操纵。
请参阅Plunker。
选项#2- debounce
这是更" hacky"的,但通常可以解决问题 - 使用debounce
函数(即lodash)使您的处理程序火只能每个x毫秒一次。也就是说,类似的东西:
$scope.stopEditTodo = _.debounce(function($index, $event, todo) {
angular.element(event.currentTarget).removeAttr('contenteditable');
// fire request
}, 300);
这应该在大多数使用方案中效果。
side Note :似乎您应该使用event.target
而不是event.currentTarget
,因为后者将始终参考父级div
而不是实际列表项目(您想要)。另外,您可以将ng-enter
移至列表项目而不是父。