简体   繁体   English

Angular $ watch仅在onclick上触发一次

[英]Angular $watch only triggered once with onclick

I have a function in an angular service containing an ajax call doing the following: 我在一个包含ajax调用的角度服务中有一个函数,执行以下操作:

function performCall($scope){
   $scope.dataFail = false;

   var promise = doAjaxCall();
   promise.then(function(data){
      if(data.rootElement){
         //process...
      }else{
         $scope.dataFail=true;
      }
   }
}

And a $watch expression in my controller watching dataFail and displaying a dialog with an option to call performCall when the dialog is confirmed: 我的控制器中的$ watch表达式正在查看dataFail,并在确认对话框时显示一个对话框,其中包含调用performCall的选项:

$scope.$watch('dataFail', function(dataFail){
    if(dataFail){
        //open dialog
        $( "#ajaxFailurePopup" ).dialog({
            zIndex: 3003,
            title: "Note:",
            modal:true, // Disable controls on parent page
            buttons: {
                Ok: {
                    text: 'Retry >',
                    "class" : 'ppButton floatRight',
                    click:
                      function() {
                                             service.performCall($scope);
                         $("#ajaxFailurePopup").remove();
                       }
                    }
                }
            });
        };
    });

This works fine on initialisation when the ajax call first fails. 当ajax调用首次失败时,这在初始化时工作正常。 However, after this no changes made to dataFail are registered by the $watch . 但是,在此之后, $watch不会对dataFail进行任何更改。 Does anybody have any suggestions? 有人有什么建议吗?

Resolved by wrapping call to performCall in $scope.apply: 通过在$ scope.apply中包含对performCall的调用来解决:

$scope.apply(
   service.performCall($scope);
)

The dataFail flag was being set in the performCall method. dataFail标志正在performCall方法中设置。 Apologies. 道歉。

There are couple of problems with your code: 您的代码有几个问题:

  1. In Angular, $watch expression callback function is called only if expression has changed the value. 在Angular中,仅当表达式更改了值时才调用$ watch表达式回调函数。 Since you're never resetting your 'dataFail' flag the expression never gets called in subsequent calls. 由于您永远不会重置“dataFail”标志,因此后续调用中永远不会调用表达式。 You should set your flag variable to false inside the $watch expression. 您应该在$ watch表达式中将flag变量设置为false。

  2. In dialog you are calling $("#ajaxFailurePopup").remove(); 在对话框中,您调用$(“#ajaxFailurePopup”)。remove(); which removes the #ajaxFailurePopup element from the DOM, hence the dialog is unable to initialize again. 从DOM中删除#ajaxFailurePopup元素,因此对话框无法再次初始化。 You should use $('#ajaxFailurePopup').dialog('destroy'); 你应该使用$('#ajaxFailurePopup')。dialog('destroy');

Working plnkr: http://embed.plnkr.co/wcooiJ 工作plnkr: http ://embed.plnkr.co/wcooiJ

Since you say that the watch fires on the first failed request, but no on subsequent failed requests, is it possible that you're not resetting $scope.dataFail to false for successful requests? 既然你说手表会在第一个失败的请求中触发,但是在后续失败的请求中没有,那么你是否可能因为成功的请求而没有将$scope.dataFail重置$scope.dataFail false? If $scope.dataFail is only set to false during initialization, the value never changes and your watch won't get called. 如果$scope.dataFail在初始化期间仅设置为false,则该值永远不会更改,并且不会调用您的监视。 Setting $scope.dataFail to true if it´s already true won't fire the watch since Angular can't tell that it changed. 如果已经为真,则将$scope.dataFail设置$scope.dataFail true将不会触发监视,因为Angular无法判断它是否已更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM