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

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

问题描述

Ionic 标签,标签的根 HTML 有RootTabCtrl",而Tab1"(带有Tab1_Ctrl")有一个表单,其他标签被禁用.

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

  1. 用户在 Tab1 上提交表单
  2. Tab1 控制器功能启动.
  3. 控制器函数调用外部函数(不在控制器中).
  4. 外部函数触发器,它执行一个承诺
  5. 在承诺results"中,处理返回的数据
  6. 如果返回数据中的 X 为真,则触发RootTabCtrl"功能以启用其他禁用的选项卡.
  7. 我可以跟踪触发每一步的控制台消息.

这一切都有效,除了以下奇怪的行为.RootTabCtrl"不会启用禁用的选项卡,直到用户单击表单第二次提交......即使我看到控制台消息说它在(最后)RootTabCtrl 函数中.我在第一次点击时看到所有相同的控制台消息 - 但第二次是禁用的选项卡再次启用时.

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.

如果我将第 6 步移到第 4 步中的 Promise 之外,并将其放在第 3 步之后(并在 Promise 之前),那么所有选项卡都会在第一次点击时启用.但是,这不再考虑 X 的值来确定是否应重新启用其他选项卡.

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'
      }
    }
  })

控制器:

.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 函数中,它是对谷歌地图的调用,如果特定数据 X 为真,则使用 tab1Ctrl $scope.enableTabs() 启用所有其他选项卡:

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) ;
          }
        });
      }
    }

上述所有工作...除了当调用 enableTabs(在 google 响应中)时,即使它正确调用了 enableTabs 并且我可以看到从 enableTabs 中触发的 console.log 消息 - 其他选项卡不t启用"直到第二次单击表单按钮(然后我再次看到所有控制台消息).我在 getGoogle() 中尝试了 2 种不同的方法,两者的工作方式完全相同 - 第一次点击正确触发了所有功能,但选项卡未启用.第二次点击触发了所有功能,然后选项卡被启用.

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.

推荐答案

试试这个以前的 回答.你在使用 $http 调用吗?如果是这样,我实际上从未这样做过,所以似乎其他原因可能是根本原因.

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.

更新

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

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('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");
    }
});

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

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 的承诺中调用控制器函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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