$ scope。$ apply在API服务调用后没有处理jQuery插件

时间:2017-08-12 05:58:42

标签: javascript jquery angularjs

我使用third party jQuery tabs plugin来浏览我的网络应用程序。下面的每个标签都有" next"按钮。单击下一个按钮时,将触发函数onNext。从那里,我可以在移动到第二个选项卡之前验证我的字段。如果我尝试验证所有字段,验证效果很好。但是当我通过API调用验证并返回数据时。它不起作用。我曾被用过$scope.$apply()setTimeOut。两者都没有用。

没有服务的控制器(工作示例)

jQuery('.js-wizard-classic-validation').bootstrapWizard({
       'tabClass': '',
       'previousSelector': '.wizard-prev',
       'nextSelector': '.wizard-next',
  'onTabShow': function(tab, nav, index) { }
  'onNext': function(tab, navigation, index) {
     if(index == 1){
       // This is when the 'next' button is click on the first tab
       var full_location_validated = false;
       // All the if else statements goes here to validate the fields
       $scope.$apply(); // Without this, next button will does nothing never update
       return full_location_validated;
     }
  }

有服务的控制器(没有工作)

jQuery('.js-wizard-classic-validation').bootstrapWizard({
       'tabClass': '',
       'previousSelector': '.wizard-prev',
       'nextSelector': '.wizard-next',
  'onTabShow': function(tab, nav, index) { }
  'onNext': function(tab, navigation, index) {
     if(index == 1){
       // This is when the 'next' button is click on the first tab
       var full_location_validated = false;

       // Assume service return (success == true)
       myService.ValidateLocation(function(success){
            if(success == true)
               full_location_validated = true;
            else
               full_location_validated = false;
       });

       /* CASE 1 */
       // $scope.$apply();
       // return full_location_validated; // it returns false

       /* CASE 2 */
       setTimeout(function(){
         $scope.$apply();
         return full_location_validated; // it returns true
       },1500);
     }
  }

问题

  

单击下一个按钮时,没有任何反应,因为full_location_validated在服务时返回false而不是true。

1 个答案:

答案 0 :(得分:0)

我在代码中看到以下问题:

1)避免使用setTimeout

如果您编写Angular应用程序,请不要使用setTimeout,而是使用$timeout。 Angular不知道setTimeout延迟,您需要使用$scope.$apply();

此代码段:

setTimeout(function(){
     $scope.$apply();
     return full_location_validated; // it returns true
   },1500);

您可以替换为:

$timeout(function (){
  return full_location_validated;
}, 1500);

2)myService.ValidateLocation其异步调用:

 myService.ValidateLocation(function(success){
        if(success == true)
           full_location_validated = true;
        else
           full_location_validated = false;
   });

// ...
 return full_location_validated;

您首先将full_location_validated作为false返回,并且仅在延迟一段时间后(在您的情况下为1500毫秒),您full_location_validated变为true

为了使其工作,我会尝试使用Promises或删除硬编码值1500ms,如:

 var releaseTimeout = false;

 myService.ValidateLocation(function(success){
        if(success == true)
           full_location_validated = true;
        else
           full_location_validated = false;
        releaseTimeout = true;   
   });


 var waitForValidate = function () {

   $timeout(function () {
       if(!releaseTimeout){
           return waitForValidate(); 
        }
        else{
         return full_location_validated; 
        }              
    }, 100);
 };

return waitForValidate();         

**没有测试

3)DOM操作和使用3d party

在控制器中进行DOM操作并使用像jQuery这样的3d派对并不是一个好习惯。为此目的创建指令。