모서리에서의 더블 버튼 클릭 방지/처리
각도에서는 다음과 같은 ajax 요청을 전송하도록 버튼을 설정할 수 있습니다.
... ng-click="button-click"
컨트롤러:
...
$scope.buttonClicked = function() {
...
...
// make ajax request
...
...
}
따라서 중복 제출을 방지하기 위해 플래그를 버튼을 클릭할 때 = true로 설정하고, Ajax 콜백이 완료되면 플래그를 설정 해제할 수 있습니다.하지만, 그 후에도 돔으로 업데이트 할 각진 사람에게 제어가 다시 처리됩니다.즉, 원래 버튼 클릭이 100% 완료되기 전에 버튼을 다시 클릭할 수 있는 작은 창이 나타납니다.
작은 창문이지만 일어날 수 있습니다.서버 업데이트를 하지 않고 클라이언트 측에서 이 문제를 완전히 회피하기 위한 힌트.
감사해요.
먼저 ngDblick을 추가하는 것이 좋습니다.이것이 더블클릭을 검출했을 경우는, 되돌리기만 하면 됩니다.false:
<ANY ng-click="buttonClicked()" ng-dblclick="return false">
Ajax 콜이 종료되기를 기다리는 경우 ng-disabled를 설정하여 버튼을 비활성화할 수 있습니다.
<ANY ng-click="buttonClicked()" ng-dblclick="return false;" ng-disabled="flag">
또한 컨트롤러에서는 다음과 같은 작업을 수행할 수 있습니다.
$scope.flag = false;
$scope.buttonClicked = function() {
$scope.flag = true;
Service.doService.then(function(){
//this is the callback for success
$scope.flag = false;
}).error(function(){
//this is the callback for the error
$scope.flag = false;
})
}
Ajax 콜이 성공했을 경우 또는 실패했을 경우 모두 diabled로 표시하여 사용자를 혼란스럽게 하지 않도록 하기 위해 둘 다 처리할 필요가 있습니다.
「」를 사용합니다.ng-disabled이 예에서는 정상적으로 동작합니다.콘솔 메시지를 아무리 세게 클릭해도 입력된 것은 한 번뿐입니다.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.submitData = function() {
$scope.buttonDisabled = true;
console.log("button clicked");
}
function augment() {
var name, fn;
for (name in $scope) {
fn = $scope[name];
if (typeof fn === 'function') {
if (name.indexOf("$") !== -1) {
$scope[name] = (function(name, fn) {
var args = arguments;
return function() {
console.log("calling " + name);
console.time(name);
fn.apply(this, arguments);
console.timeEnd(name);
}
})(name, fn);
}
}
}
}
augment();
});
<!doctype html>
<html ng-app="plunker">
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<input type="button" ng-click="submitData()" ng-disabled="buttonDisabled" value="Submit" />
</body>
</html>
각도가 바뀌는데 정확히 얼마나 걸리는지 궁금했어요buttonDisabled플래그가 표시됩니다.플런커의 예에서 콘솔을 체크하면, 이 예에서는, 이 플래그가 동작하는 데 걸리는 시간이 표시됩니다.$eval ★★★★★★★★★★★★★★★★★」$apply실행 방법을 지정합니다.제 기계에서는 평균 1~2밀리초가 걸렸습니다.
방금 zsong의 코드를 확장해서 플래그의 핸들러에 체크 표시를 추가했습니다.만약 그것이 사실이라면 클릭이 이미 처리되고 있기 때문에 그냥 돌아가세요.각진 타이밍 등에 신경 쓰지 않고 더블 클릭을 방지할 수 있습니다.
$scope.flag = false;
$scope.buttonClicked = function() {
if ($scope.flag) {
return;
}
$scope.flag = true;
Service.doService.then(function(){
//this is the callback for success
$scope.flag = false;
}).error(function(){
//this is the callback for the error
$scope.flag = false;
})
}
사용자가 비동기 작업을 수행할 때 요소를 여러 번 클릭하지 않도록 방금 완료한 지시어를 사용할 수 있습니다.
https://github.com/mattiascaricato/angular-click-and-wait
npm 또는 bower를 사용하여 프로젝트에 추가할 수 있습니다.
npm install angular-click-and-wait
또는
bower install angular-click-and-wait
사용 예
const myApp = angular.module('myApp', ['clickAndWait']);
myApp.controller('myCtrl', ($scope, $timeout) => {
$scope.asyncAction = () => {
// The following code simulates an async action
return $timeout(() => angular.noop, 3000);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://cdn.rawgit.com/mattiascaricato/angular-click-and-wait/master/dist/click-and-wait.js"></script>
<section ng-app="myApp">
<div ng-controller="myCtrl">
<button click-and-wait="asyncAction()">Click Me!</button>
</div>
</section>
주의: 인수로 전달된 비동기 액션은 Promise여야 합니다.
사용자: zsong의 솔루션이 마음에 들었습니다.
그러나 ng-dblclick="return false;"는 js 콘솔에서 문제(Chrome Windows 7 사용 중)를 발생시킵니다.
코멘트를 할 수 없다(솔루션 코멘트를 할 만한 평판이 없다)
ng-disabled만 사용합니다.
아래 플런커에서 볼 수 있듯이 ng-click과 ng-dblick의 두 가지 기능이 있는 경우 두 번 클릭하면 실행됩니다: 2번 클릭과 1번 dblick
<bla ng-dblclick="count=count+1" ng-click="count=count+0.1" />
두 번 클릭하면 1.2가 표시되므로 ng-dblick으로 두 번 클릭하는 것을 막을 수 없습니다. 두 번째 클릭이 발생할 때 한 번만 더 추가해 주세요.
Jonathan Palumbo는 이 스레드에서 ng-disabled 작업의 예를 제시했습니다.
저는 최근에 이 작업을 해야 했고, 몇 가지 해결책을 모았습니다.이 명령어는 ng-click을 대체하는 명령어로, 한 번만 클릭할 수 있습니다.
이 솔루션은 오류를 발생시키기 때문에 매우 쉽게 테스트할 수 있습니다.
.directive('oneClickOnly', [
'$parse', '$compile', function($parse, $compile) {
return {
restrict: 'A',
compile: function(tElement, tAttrs) {
if (tAttrs.ngClick)
throw "Cannot have both ng-click and one-click-only on an element";
tElement.attr('ng-click', 'oneClick($event)');
tElement.attr('ng-dblclick', 'dblClickStopper($event)');
tElement.removeAttr('one-click-only');
var fn = $parse(tAttrs['oneClickOnly']);
return {
pre: function(scope, iElement, iAttrs, controller) {
console.log(scope, controller);
var run = false;
scope.oneClick = function(event) {
if (run) {
throw "Already clicked";
}
run = true;
$(event.toElement).attr('disabled', 'disabled');
fn(scope, { $event: event });
return true;
};
scope.dblClickStopper = function(event) {
event.preventDefault();
throw "Double click not allowed!";
return false;
};
$compile(iElement)(scope);
}
};
},
scope: true
};
}
])
테스트 내용입니다(관심있는 분들을 위해).
'use strict';
describe("The One click button directive", function() {
var $scope, testButton, $compile, clickedEvent;
var counter = 0;
beforeEach(function () {
counter = 0;
module('shared.form.validation');
inject(function ($rootScope, _$compile_) {
$compile = _$compile_;
$scope = $rootScope.$new();
$scope.clickEvent = function (event) {
counter++;
};
});
});
it("prevents a button from being clicked multiple times", function () {
var html = "<a one-click-only='clickEvent()'>test button</a>";
testButton = $compile(html)($scope);
$scope.$digest();
testButton.click();
expect(function () { testButton.click(); }).toThrow("Already clicked");
expect(counter).toBe(1);
});
it("doesn't allow ng-click on the same tag", function() {
var html = "<a ng-click='clickEvent()' one-click-only='clickEvent()'>test button</a>";
expect(function () { $compile(html)($scope); }).toThrow("Cannot have both ng-click and one-click-only on an element");
});
it("works for multiple buttons on the same scope", function () {
var counter2 = 0;
$scope.clickEvent2 = function (event) {
counter2++;
};
var html = "<a one-click-only='clickEvent()'>test button</a>";
var html2 = "<a one-click-only='clickEvent2()'>test button</a>";
testButton = $compile(html)($scope);
var testButton2 = $compile(html2)($scope);
$scope.$digest();
testButton.click();
expect(function () { testButton2.click(); }).not.toThrow("Already clicked");
expect(counter).toBe(1);
expect(counter2).toBe(1);
});
});
바와 같이 「」를 합니다.ng-disabled문제가 해결됩니다.여기에 설명하려고 플런커를 만들었어요.
@Jonathan Palumbo의 답변(ngDisabled 사용)과 @andre의 질문("컨트롤러 대신 명령어로 그것을 사용하는 방법")에 대해 자세히 설명하려면 클릭 가능 요소(버튼, 링크, 범위 또는 div)에 대해 타임아웃 함수 내에서 프로그래밍 방식으로 '비활성화' 속성을 설정해야 합니다.n(지연 0ms)을 사용하여 이벤트를 디세블로 하기 전에 전달할 수 있습니다.
$timeout(function(){ elm.attr('disabled',true); }, 0);
@arun-p-johny의 답변을 참조해 주세요: angular.js - disable form 버튼을 사용하여 여러 폼을 제출하지 않도록 합니다.
더블클릭을 방지하는 지시문을 작성할 수 있습니다.
angular.module('demo').directive('disableDoubleClick', function ($timeout) {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
elem.bind('click', function(){
$timeout(function(){
elem.attr('disabled','disabled');
}, 20);
$timeout(function(){
elem.removeAttr('disabled');
}, 500);
});
}
};
});
이렇게 클릭 가능한 항목에 사용할 수 있습니다.
<button ng-click="clickMe()" disable-double-click >Click Me</button>
중 의 답변에 된 바와 , 는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ng-dbliclick="return false;"JS에 대해서요.
에서는, ★★★★★★★★★★★★★★★★★★★★.ng-dblclick="return"이치노 기능은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 에서만 기능합니다.<form>붙이다
zsong의 doe에서 다시 확장하려면:
먼저, 이 솔루션을 통해 사람들은 더블클릭을 사용하여 당신의 앱을 사용할 수 있습니다.노인들은 가끔 그렇게 하고(창에서 프로그램을 두 번 클릭해서 열 때 사용되었기 때문에), 다른 사람들도 실수로 그렇게 한다.
둘째, 사용자는 가능한 한 빨리 클릭할 수 있습니다.브라우저는 버튼을 다시 활성화하기 전에 서버 응답을 기다립니다(이것은 zsong의 투고에 대한 Mark Rajcok의 코멘트를 수정한 것입니다: "AJAX 요청이 브라우저의 더블 클릭 시간/창보다 오래 걸린다면, 이것은 작동하지 않습니다.즉, 사용자가 일시 정지했다가 다시 클릭할 수 있습니다.")
html에서
<ANY
ng-click="buttonClicked();
submitButtonDisabled = 1 + submitButtonDisabled;"
ng-disabled="submitButtonDisabled > 0;"
ng-init="submitButtonDisabled = 0;"
>
컨트롤러 내
$scope.buttonClicked = function() {
Service.doService.then(function(){
//this is the callback for success
// you probably do not want to renable the button here : the user has already sent the form once, that's it - but just if you want to :
$scope.submitButtonDisabled --;
//display a thank you message to the user instead
//...
}).error(function(){
//this is the callback for the error
$scope.submitButtonDisabled --;
})
}
제가 찾은 간단한 해결책은 다른 답변보다 낫다고 생각되는 것은 mouchdown 이벤트에서 브라우저의 기본 동작을 방지하는 것입니다.
ng-mousedown="$event.preventDefault();"
클릭 이벤트는 방지하지 않지만 더블 클릭 이벤트는 방지합니다.
You can handle the form validation
$('form.your-form').validate({
rules: {
name: 'required',
email: {
required: true,
email: true
}
},
submitHandler: function (form) {
// Prevent double submission
if (!this.beenSubmitted) {
this.beenSubmitted = true;
form.submit();
}
}
});
언급URL : https://stackoverflow.com/questions/18130808/preventing-dealing-with-double-button-clicks-in-angular
'programing' 카테고리의 다른 글
| jQuery.getJSON - 접근컨트롤-허용-발신원 문제 (0) | 2023.03.06 |
|---|---|
| JSON의 이스케이프 문자 대체 (0) | 2023.03.06 |
| JsonNode에 새 노드를 만드는 방법 (0) | 2023.03.06 |
| gson이 Malformed Json Exception을 슬로우하다 (0) | 2023.03.06 |
| 커스텀 투고 타입에 기본 카테고리/태그 분류법을 재사용하시겠습니까? (0) | 2023.02.11 |