Вызов функции контроллера из обещания во внешнем JS
Ионные вкладки, корень вкладок HTML имеет "RootTabCtrl", а "Tab1" (с "Tab1_Ctrl") имеет форму, другие вкладки отключены.
- Пользователь отправляет форму на Tab1
- Функция Tab1 Controller запускается.
- Функция контроллера вызывает внешнюю функцию (не в контроллере).
- Триггеры внешней функции, которые выполняют обещание
- В обещании "результаты" возвращенные данные обрабатываются
- Если X в возвращаемых данных равно true, активируйте функцию "RootTabCtrl", чтобы включить другие отключенные вкладки.
- Я могу отслеживать консольные сообщения, которые запускаются на каждом этапе.
Это все работает, за исключением следующего странного поведения. "RootTabCtrl" не включает отключенные вкладки до тех пор, пока пользователь не щелкнет форму, отправив ее во второй раз... хотя я вижу консольные сообщения о том, что она находится в конце функции RootTabCtrl. Я вижу все те же сообщения консоли с первого щелчка - но во 2-й раз, когда отключенные вкладки снова включаются.
Если я переместлю шаг 6 за пределы обещания на шаге 4 и поместу его после шага 3 (и до обещания), то все вкладки будут активированы при первом щелчке. Однако это больше не принимает во внимание значение 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, это вызов карт 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 (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, и я вижу, что сообщения console.log стреляют изнутри enableTabs - другие вкладки "не включаются" msgstr "до тех пор, пока кнопка формы не будет нажата во второй раз (а затем я снова увижу все сообщения консоли). Я попробовал 2 разных метода, изнутри getGoogle(), оба работали одинаково - 1-й щелчок включил все функции правильно, но вкладки не активировались. 2-й щелчок запустил все функции, а затем активировались вкладки.
1 ответ
Попробуйте этот предыдущий ответ. Вы используете $http звонки? Если так, то мне никогда не приходилось это делать, поэтому кажется, что причиной может быть что-то другое.
ОБНОВИТЬ
Как насчет создания службы Angular для этого вызова функции GetGoogle. Тогда вы все еще будете внутри Angular и сможете вводить $rootScope и все остальное, что вам нужно. Вам нужно будет внедрить этот сервис в ваш tab1Ctrl (myGoggleService ниже). Я также, вероятно, просто передам форму обратно в 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('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 {
}
});
}
}}]);
Я скопировал ваш код сверху, а затем просто удалил некоторые дополнительные вещи, просто чтобы понять суть. Очевидно, что не удалось запустить код, поэтому могут возникнуть некоторые ошибки или небольшие изменения, но, надеюсь, это приблизит вас.