2016-05-31 82 views
0

離子選項卡,選項卡的根HTML有「RootTabCtrl」和「Tab1」(與「Tab1_Ctrl」)有一個窗體,其他選項卡禁用呼叫控制器功能從一個承諾在外部JS

  1. 用戶提交表單上TAB1
  2. TAB1控制器功能序幕。
  3. 控制器函數調用外部函數(不在控制器中)。
  4. 外部函數觸發時,執行一個承諾
  5. 在承諾「結果」,返回數據被處理
  6. 如果X在返回的數據是真實的,觸發「RootTabCtrl」功能,以使其他禁用的選項卡。
  7. 我可以跟蹤控制檯消息觸發每一步的方式。

這一切都有效,除了下面這個奇怪的行爲。 「RootTabCtrl」不會啓用禁用的選項卡,直到用戶再次單擊表單提交即使我看到控制檯消息說它位於RootTabCtrl函數的末尾。我從第一次點擊看到所有相同的控制檯消息 - 但第二次是禁用的選項卡再次啓用時。

如果我在第4步中將承諾移出步驟6之外,並將其放在第3步之後(並在承諾之前),則所有選項卡將在第1次點擊中啓用。但是,這不再考慮X的值來確定是否應該重新啓用其他選項卡。

我可以尋找什麼,或者我不知道,會導致這種情況?

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()使所有其他選項卡:

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(在谷歌響應中),即使它正確調用enableTabs,我可以看到console.log消息從enableTabs中觸發 - 其他選項卡不會「啓用」,直到第二次單擊窗體按鈕(然後再次看到所有控制檯消息)。我在getGoogle()中嘗試了兩種不同的方法,兩種方法完全相同 - 第一次點擊正確啓動所有功能,但選項卡未啓用。第二次點擊激活了所有功能,然後啓用了選項卡。

+1

嘗試使用範圍更新你的'$ scope' $ apply()' –

+0

在這兩種方法中,我得到了一個方法,將它添加到下面的答案中。但仍然在尋找第二種方法。 – rolinger

+0

爲什麼你不使用承諾從'getGoogle()'獲取返回值? –

回答

0

試試這個前面的answer。你使用$ http呼叫嗎?如果是這樣,我從來沒有真的必須這樣做,所以看起來其他東西可能是根本原因。

UPDATE

怎麼樣在這個GetGoogle函數調用創建一個Angular Service。然後你仍然會處於角度之內,並且可以注入$ rootScope和其他任何你需要的東西。您需要將此服務注入到tab1Ctrl(下面的myGoggleService)中。我也很可能只是通過形式回到了NG-提交:

的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('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 { 

     } 
    }); 
    } 
}}]); 

我沒有從上面複製你的代碼,然後只是刪除了一些額外的東西,只是爲了獲得點。顯然無法運行代碼,因此可能會出現一些錯誤或需要稍作更改,但希望這會讓您接近。