Chcę, żeby coś się zaczęło ng-mousedown
i zakończyć na mouseup. Chcę również, aby coś się działo, podczas gdy przycisk myszy pozostanie w dół, jeśli mysz opuści element. Dosyć powszechnym sposobem implementacji tego w javascriptie wanilii jest powiązanie zdarzenia mouseupup dokumentu w zdarzeniu mousedown elementu, tak jak:
HTML:
<button onMouseDown="onMouseDown()">Click Me</button>
<div id="val"></div>
JS:
function onMouseDown() {
var el = document.querySelector("#val"),
changeValue = function() {
el.innerHTML = "done!";
document.removeEventListener("mouseup", changeValue);
};
el.innerHTML = "waiting for mouseup...";
document.addEventListener("mouseup", changeValue);
}
Mam problem z zaimplementowaniem tego zachowania w programie Angular z jQuery " one()
, angular.element.one
, i addEventListener
/ removeEventListener
:
HTML:
<div ng-app="MyApp" ng-controller="AppCtrl">
<div>Note that "done!" is not rendered, despite "mouseup" being logged to the console</div>
<button ng-mousedown="changeValue()">Click Me</button>
<div>{{value}}</div>
</div>
JS (jQuery "s one()
):
angular
.module("MyApp", [])
.controller("AppCtrl", function($scope) {
$scope.changeValue = function() {
console.log("mousedown");
$scope.value = "waiting for mouseup...";
$(document).one("mouseup", function() {
console.log("mouseup");
$scope.value = "done!";
});
}
});
JS (angular.element.one
):
angular
.module("MyApp", [])
.controller("AppCtrl", function($scope) {
$scope.changeValue = function() {
console.log("mousedown");
$scope.value = "waiting for mouseup...";
angular.element(document).one("mouseup", function() {
console.log("mouseup");
$scope.value = "done!";
});
}
});
JS (addEventListener
/ removeEventListener
):
angular
.module("MyApp", [])
.controller("AppCtrl", function($scope) {
$scope.changeValue = function() {
var changeValue = function() {
console.log("mouseup");
$scope.value = "done!";
document.removeEventListener("mouseup", changeValue);
};
console.log("mousedown");
$scope.value = "waiting for mouseup...";
document.addEventListener("mouseup", changeValue);
}
});
Próbowałem też dźwigni ng-mouseup
i ng-mouseleave
lubię to:
HTML:
<div ng-app="MyApp" ng-controller="AppCtrl">
<div>While clicking the button, move the mouse off of the button and release the mouse button. Note that "done!" is not rendered, despite "mouseup" being logged to the console</div>
<button ng-mousedown="mouseDown()" ng-mouseup="mouseUp()" ng-mouseleave="mouseLeave()">Click Me</button>
<div>{{value}}</div>
</div>
JS:
angular
.module("MyApp", [])
.controller("AppCtrl", function($scope) {
$scope.mouseDown = function() {
console.log("mousedown");
$scope.value = "waiting for mouseup...";
}
$scope.mouseUp = function() {
console.log("mouseup");
$scope.value = "done!";
}
$scope.mouseLeave = function() {
if ($scope.value && $scope.value.indexOf("waiting") > -1) {
console.log("mouseleave, binding mouseup");
$(document).one("mouseup", function() {
$scope.mouseUp();
});
}
}
});
Wynik jest taki sam. $scope.mouseUp
jest wykonywane, ale "done!"
nigdy nie jest renderowany. Powoduje to dodatkowe problemy z $scope.$watch
:
HTML:
<div ng-app="MyApp" ng-controller="AppCtrl">
<div>value never === "done!" in $scope.$watch</div>
<button ng-mousedown="changeValue()">Click Me</button>
<div>{{value}}</div>
</div>
JS:
angular
.module("MyApp", [])
.controller("AppCtrl", function($scope) {
$scope.changeValue = function() {
console.log("mousedown");
$scope.value = "waiting for mouseup...";
$(document).one("mouseup", function() {
console.log("mouseup");
$scope.value = "done!";
});
}
$scope.$watch("value", function(value) {
if (value === "done!") {
console.log("value set to "done!"");
}
});
});
Odpowiedzi:
2 dla odpowiedzi № 1Nie mam pojęcia, dlaczego to pytanie pozostało bez odpowiedzi przez ponad miesiąc.
Główny problem tutaj jest prosty - kod, który aktualizuje $scope.value
jest wykonywany poza AngularJS. Aby powiązanie danych działało, należy je opakować $scope.$apply
lubię to:
$scope.$apply(function () {
$scope.value = "done!";
});
Zauważ, że ng-mouseup
działa dobrze, widać to po uruchomieniu myszy nad przyciskiem. Ale jeśli przesuniesz mysz poza przycisk $(document).one("mouseup"..)
wydarzenie nastąpi.
Pamiętaj, że musisz zawijać wszystkie zewnętrzne wywołania zwrotne $scope.$apply
(Wywołania zwrotne HTTP JQuery, zdarzenia DOM nie są wiązane z dyrektywami ng- *, setTimeout
itp.), jeśli potrzebujesz go do pracy z oprawą AngularJS lub obserwatorami. Ale pomyśl dwa razy - dzwoniąc $scope.$apply
w innym $scope.$apply
spowoduje błąd.
Możesz przejrzeć dokumentacja lub czytaj więcej tutaj.