最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular $watch only triggered once with onclick - Stack Overflow

programmeradmin1浏览0评论

I have a function in an angular service containing an ajax call doing the following:

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:

$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. However, after this no changes made to dataFail are registered by the $watch. Does anybody have any suggestions?

I have a function in an angular service containing an ajax call doing the following:

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:

$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. However, after this no changes made to dataFail are registered by the $watch. Does anybody have any suggestions?

Share Improve this question asked Feb 25, 2013 at 16:28 noiselesslarknoiselesslark 1012 silver badges6 bronze badges 2
  • you have extra space in event. 'dataFail ' <=== well, guessed it. – Talha Akbar Commented Feb 25, 2013 at 16:31
  • Unfortunately not relevant in this case since this problem does not exist in the original code. This is merely an outline of what the code does. Amended in example. – noiselesslark Commented Feb 25, 2013 at 16:34
Add a ment  | 

3 Answers 3

Reset to default 4

Resolved by wrapping call to performCall in $scope.apply:

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

The dataFail flag was being set in the performCall method. 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. Since you're never resetting your 'dataFail' flag the expression never gets called in subsequent calls. You should set your flag variable to false inside the $watch expression.

  2. In dialog you are calling $("#ajaxFailurePopup").remove(); which removes the #ajaxFailurePopup element from the DOM, hence the dialog is unable to initialize again. You should use $('#ajaxFailurePopup').dialog('destroy');

Working 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? If $scope.dataFail is only set to false during initialization, the value never changes and your watch won't get called. Setting $scope.dataFail to true if it´s already true won't fire the watch since Angular can't tell that it changed.

发布评论

评论列表(0)

  1. 暂无评论