在 Angular JS 中使用 $watch 设置监听器
Setting up a listener with $watch in Angular JS
我有一个服务连续两次异步调用 API。
我希望应用程序在继续之前等待两者都得到解决,并且由于可能会或可能不会进行其中一个调用,我相信 $watch
是与嵌套或链式回调相比的方法。
var response_complete = {call1:false, call2:false};
$http.post("myapi.com/slug", data, header).then(function(res){
/* ... */
response_complete.call1 = true;
});
if(make_this_call==true){
$http.post("myapi.com/anotherslug", data, header).then(function(res){
/*...*/
response_complete.call2 = true;
});
} else response_complete.call2 = true;
$scope.$watch("response_complete",function(){
if(response_complete.call1==true && response_complete.call2==true){
console.log("DONE!");
}
});
所以我的想法是创建一个全局变量,并在两个调用完成时观察它。第二次调用是有条件的,如果未进行,则立即将其响应变量设置为 true
。
但是 $watch
回调只被触发一次,其中的条件 (call1 & call2 == true) 永远不会满足。
如果您需要当前范围的 "global" 变量,您可以这样做:
$scope.complete = false;
$http.post("myapi.com/slug", data, header).then(function(res) {
$http.post("myapi.com/anotherslug", data, header).then(function(res) {
$scope.complete = true;
console.log("DONE!");
});
});
您也可以使用 $rootScope 获得更多 "global" 值。其他替代方案是 $broadcast 或服务内的 属性。
但更重要的是确保您如何使用异步调用。如果您希望两者都得到解决,请将第二个调用放在第一个调用中。您提供的示例不起作用,因为 response_complete.call1 = true 在异步线程中,并且在您尝试验证它时它始终为 false
您的手表不工作,因为响应完成不是 $scope
变量 | 属性:
// replace this with $scope property declaration
//var response_complete = {call1:false, call2:false};
$scope.response_complete = {call1:false, call2:false};
然后在您的后续代码中使用 $scope.response_complete
修改其值,因此您的 $watch
将在 $scope.response_complete
更改时触发。
更好的解决方案:
正如其他人所指定的那样,使用 $broadcast
比 $watch
更好,因此请改为观察变量抛出事件并在 $scope
.[=19= 中捕获这些事件]
$http.post("myapi.com/slug", data, header).then(function() {
// stuff
$scope.$broadcast("POST_SLUG_COMPLETE");
});
$http.post("myapi.com/anotherslug", data, header).then(function() {
// stuff
$scope.$broadcast("POST_ANOTHERSLUG_COMPLETE");
});
// then in your $scope
$scope.$on("POST_SLUG_COMPLETE", function () {
// stuff
});
$scope.$on("POST_ANOTHERSLUG_COMPLETE", function () {
// stuff
});
希望对您有所帮助
我有一个服务连续两次异步调用 API。
我希望应用程序在继续之前等待两者都得到解决,并且由于可能会或可能不会进行其中一个调用,我相信 $watch
是与嵌套或链式回调相比的方法。
var response_complete = {call1:false, call2:false};
$http.post("myapi.com/slug", data, header).then(function(res){
/* ... */
response_complete.call1 = true;
});
if(make_this_call==true){
$http.post("myapi.com/anotherslug", data, header).then(function(res){
/*...*/
response_complete.call2 = true;
});
} else response_complete.call2 = true;
$scope.$watch("response_complete",function(){
if(response_complete.call1==true && response_complete.call2==true){
console.log("DONE!");
}
});
所以我的想法是创建一个全局变量,并在两个调用完成时观察它。第二次调用是有条件的,如果未进行,则立即将其响应变量设置为 true
。
但是 $watch
回调只被触发一次,其中的条件 (call1 & call2 == true) 永远不会满足。
如果您需要当前范围的 "global" 变量,您可以这样做:
$scope.complete = false;
$http.post("myapi.com/slug", data, header).then(function(res) {
$http.post("myapi.com/anotherslug", data, header).then(function(res) {
$scope.complete = true;
console.log("DONE!");
});
});
您也可以使用 $rootScope 获得更多 "global" 值。其他替代方案是 $broadcast 或服务内的 属性。
但更重要的是确保您如何使用异步调用。如果您希望两者都得到解决,请将第二个调用放在第一个调用中。您提供的示例不起作用,因为 response_complete.call1 = true 在异步线程中,并且在您尝试验证它时它始终为 false
您的手表不工作,因为响应完成不是 $scope
变量 | 属性:
// replace this with $scope property declaration
//var response_complete = {call1:false, call2:false};
$scope.response_complete = {call1:false, call2:false};
然后在您的后续代码中使用 $scope.response_complete
修改其值,因此您的 $watch
将在 $scope.response_complete
更改时触发。
更好的解决方案:
正如其他人所指定的那样,使用 $broadcast
比 $watch
更好,因此请改为观察变量抛出事件并在 $scope
.[=19= 中捕获这些事件]
$http.post("myapi.com/slug", data, header).then(function() {
// stuff
$scope.$broadcast("POST_SLUG_COMPLETE");
});
$http.post("myapi.com/anotherslug", data, header).then(function() {
// stuff
$scope.$broadcast("POST_ANOTHERSLUG_COMPLETE");
});
// then in your $scope
$scope.$on("POST_SLUG_COMPLETE", function () {
// stuff
});
$scope.$on("POST_ANOTHERSLUG_COMPLETE", function () {
// stuff
});
希望对您有所帮助