在外部JS中的promise内调用控制器函数 [英] calling controller function from within a promise in external JS

查看:315
本文介绍了在外部JS中的promise内调用控制器函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ionic选项卡,标签的根HTML具有RootTabCtrl,Tab1(带有Tab1_Ctrl)具有表单,其他标签禁用


  1. 用户在Tab1上提交表单

  2. Tab1控制器功能启动。

  3. 控制器函数调用外部函数(不在控制器中)。

  4. 执行promise的外部函数触发器

  5. 在承诺的结果中处理返回的数据

  6. 如果返回数据中的X为true,则触发RootTabCtrl函数以启用其他已停用的标签。 $ b
  7. 我可以跟踪控制台消息触发的每一步。

这一切都有效,除了这种奇怪的行为。 RootTabCtrl不启用禁用的选项卡,直到用户单击表单提交第二次...即使我看到控制台消息说它是在(在结束)RootTabCtrl函数。



如果我将步骤6移动到承诺之外,我将看到第一次点击时所有相同的控制台讯息。在步骤4,并将其放在步骤3(和承诺之前),然后所有的选项卡启用第一次点击。但是,这不再考虑X的值来确定是否应重新启用其他标签。



我可以找什么,或者不是

app.js:

  .state('tab',{
url:/ tab,
abstract:true,
templateUrl:templates / tabs.html,
controller: TabsCtrl'
})

//每个标签都有自己的导航历史堆栈:

.state('tab.tab1',{
url :'/ map',
views:{
'tab-1':{
templateUrl:'templates / tab-1.html',
controller:'tab1Ctrl'
}
}
})

controllers:

  .controller('TabsCtrl',function($ scope,$ rootScope,constants){
$ scope.constants = constants;
$ scope.tabControl = {
disableRides:true,
disableBikes:true,
disableTransit:true
}

var refreshFinalizer = $ rootScope 。$ on('updateTabsRefresh',function(event,data){
console.log(Refresher 1);
$ scope.tabcontrol.disableTab2 = false;
$ scope.tabControl.disableTab3 = false;
console.log(Refresher 2);
});

$ scope。$ on('$ destroy',function(){
console.log(Destroy);
refreshFinalizer();
} ;
})

.controller('tab1Ctrl',function($ scope,$ rootScope){

$ scope.setInfo = function(){
getGoogle(document.getElementById('form_data')。value,0);
}
$ scope.enableTabs = function(type){
console.log(Here enableTabs1);
$ rootScope。$ broadcast('updateTabsRefresh');
console.log(Here enableTabs2);
}
})

Tab1有一个表单,点击后,它执行$ scope.setInfo。然后getGoogle()在一个外部JS函数,它调用google地图,如果特定数据X是真的,然后启用所有其他标签使用tab1Ctrl $ scope.enableTabs():

  function getGoogle(userInfo,clear){
console.log(setInfo 1);
geoCoder.geocode({'address':userInfo},function(results,status){
if(status == google.maps.GeocoderStatus.OK){
if ]){
//删除额外的代码
startPointSet = 1;
// tab1Ctrl html的ID为Tab1
angular.element(document.getElementById('Tab1') ).scope()。enableTabs();
/ *替代方法,工作方式与上一行相同但有相同问题
var $ sBody = angular.element(document.body);
var $ sRootScope = $ sBody.injector()。get('$ rootScope');
$ sRootScope。$ broadcast('updateTabsRefresh');
* /
console.log(setInfo 2);
}
} else {
//删除额外代码
console.log(response);
}
}
}
}

调用enableTabs(在google响应内),即使它正确地调用enableTabs,我可以看到console.log消息从enableTabs内触发 - 其他选项卡不会启用,直到形式按钮第二次点击然后我再次看到所有的控制台消息)。我尝试了两种不同的方法,从getGoogle()内,两者工作完全相同 - 第一次点击激活所有功能正确,但选项卡未启用。第二次点击启用所有功能,然后启用标签。

解决方案

尝试此前answer 。您使用$ http通话吗?



UPDATE



如何为此GetGoogle函数调用创建 Angular服务 。然后你仍然会在角度内,可以注入$ rootScope和你需要的任何东西。您需要将此服务注入到您的tab1Ctrl(下面的myGoggleService)。我也可能只是将表单传递回ng-submit:



Html

  ng-submit =setInfo(formNameGoesHere)

控制器

  .controller('tab1Ctrl',function($ scope,$ rootScope,myGoogleService){
$ scope.setInfo = function {
myGoogleService.getGoogle(form);
}
$ scope.enableTabs = function(type){
console.log(Here enableTabs1);
$ rootScope。$ broadcast('updateTabsRefresh');
console.log(Here enableTabs2);
}
});

服务:如果您还没有创建任何已经,您将需要注册它在您的app.js像任何指令一样,并像普通控制器一样将它们放入您的index.html页面。

  .service('myGoggleService' ,['$ rootScope',function($ rootScope){
this.getGoogle = function(userInfo,clear){
console.log(setInfo 1);
geoCoder.geocode {'address':userInfo},function(results,status){
if(status == google.maps.GeocoderStatus.OK){
$ rootScope。$ broadcast(updateTabsRefresh);
} else {

}
});
}
}}]);

我从上面复制了你的代码,然后只是删除一些额外的东西,跨越。显然无法运行代码,所以可能会有一些错误或需要轻微的更改,但希望这会让你关闭。


Ionic Tabs, root of tabs HTML has "RootTabCtrl", and "Tab1" (with "Tab1_Ctrl") has a form, other tabs are disabled.

  1. User submits form on Tab1
  2. Tab1 Controller function kicks off.
  3. Controller Function calls an external function (not in controller).
  4. External function triggers, which executes a promise
  5. In promise "results", returned data is processed
  6. If X in returned data is true, trigger "RootTabCtrl" function to enable the other disabled tabs.
  7. I can track console messages triggering every step of the way.

This all works except for this following odd behavior. "RootTabCtrl" doesn't enable the disabled tabs until the user clicks the form submit a second time...even though I see console messages saying it is in (at the end) of the RootTabCtrl function. I see all the same console messages from the first click - but on the 2nd time is when the disabled tabs get enabled again.

If I move step 6 outside of the promise in Step 4, and put it after step 3 (and before the promise), then all the tabs get enabled on the 1st click. However, this is no longer taking into account the value of X to determine if other tabs should be re-enabled or not.

What can I look for, or am not aware of, that would be causing this?

app.js:

 .state('tab', {
    url: "/tab",
    abstract: true,
    templateUrl: "templates/tabs.html",
    controller: 'TabsCtrl'
  })

  // Each tab has its own nav history stack:

  .state('tab.tab1', {
    url: '/map',
    views: {
      'tab-1': {
        templateUrl: 'templates/tab-1.html',
        controller: 'tab1Ctrl'
      }
    }
  })

controllers:

.controller('TabsCtrl', function($scope,$rootScope,constants) {
  $scope.constants = constants ;
  $scope.tabControl = { 
    disableRides : true,
    disableBikes : true,
    disableTransit : true
  }

  var refreshFinalizer = $rootScope.$on('updateTabsRefresh', function (event, data) {
    console.log("Refresher 1") ;
     $scope.tabControl.disableTab2 = false;
     $scope.tabControl.disableTab3 = false ;
     console.log("Refresher 2") ;
  });

  $scope.$on('$destroy', function () {
    console.log("Destroy") ;
    refreshFinalizer ();
  });
})

.controller('tab1Ctrl', function($scope,$rootScope) {

  $scope.setInfo= function() {
    getGoogle(document.getElementById('form_data').value,0);
  }
  $scope.enableTabs = function(type) {
    console.log("Here enableTabs1") ;
    $rootScope.$broadcast('updateTabsRefresh');
    console.log("Here enableTabs2") ;    
  }
})

Tab1 has a form, upon click, it executes $scope.setInfo. Then getGoogle() is in an outside JS function, its a call to google maps, and if specific data X is true, then enable all the other tabs using tab1Ctrl $scope.enableTabs() :

    function getGoogle(userInfo,clear) {
        console.log("setInfo 1") ;
        geoCoder.geocode({'address': userInfo}, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            if (results[0]) {
              // extra code removed
              startPointSet = 1;
           // tab1Ctrl html has id of "Tab1" 
angular.element(document.getElementById('Tab1')).scope().enableTabs();
              /* alternative method, worked the same as previous line but with same problem 
              var $sBody = angular.element(document.body) ;
              var $sRootScope = $sBody.injector().get('$rootScope') ;
              $sRootScope.$broadcast('updateTabsRefresh') ;
              */
              console.log("setInfo 2") ;
            }
          } else {
            // extra code removed
            console.log(response) ;
          }
        });
      }
    }

All of the above works...except that when the call to enableTabs (within the google response), even though it correctly calls enableTabs and I can see the console.log messages firing from within enableTabs - the other tabs don't "enable" until the form button is clicked a 2nd time (and then I see all the console messages again). I tried 2 different methods, from within getGoogle(), both worked exactly the same - 1st clicked fired all functions correctly, but tabs did not enable. 2nd click fired all the functions and then the tabs got enabled.

解决方案

Try this previous answer. Are you using $http calls? If so I have never actually had to do that so it seems like something else might be the root cause.

UPDATE

How about creating an Angular Service for this GetGoogle function call. Then you will still be inside of angular and can inject $rootScope and anything else that you need. You will need to inject this service into your tab1Ctrl (the myGoggleService below). I would also probably just pass the form back on the ng-submit:

Html

ng-submit="setInfo(formNameGoesHere)"

Controller

.controller('tab1Ctrl', function($scope, $rootScope, myGoogleService) {
    $scope.setInfo = function(form) {
        myGoogleService.getGoogle(form);
    }
    $scope.enableTabs = function(type) {
        console.log("Here enableTabs1");
        $rootScope.$broadcast('updateTabsRefresh');
        console.log("Here enableTabs2");
    }
});

Service: If you haven't created any already you will need to register it in your app.js like any directives you have and also put them in your index.html page like a regular controller.

.service('myGoggleService', [ '$rootScope', function ($rootScope) {
  this.getGoogle = function(userInfo,clear) {
    console.log("setInfo 1") ;
    geoCoder.geocode({'address': userInfo}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            $rootScope.$broadcast("updateTabsRefresh");
        } else {

        }
    });
  }
}}]);

I did copy your code from above and then just removed some of the extra stuff just to get the point across. Obviously could not run the code so there might be some mistakes or slight changes needed, but hopefully this will get you close.

这篇关于在外部JS中的promise内调用控制器函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆