/ / Powiąż documentup w ng-mousedown - javascript, jquery, angularjs, javascript-events, mousedown

Bindowanie dokumentu w ng-mousedown - javascript, jquery, angularjs, javascript-events, mousedown

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 № 1

Nie 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- *, setTimeoutitp.), 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.