Я опубликовал этот вопрос раньше, и я честно не знаю, что я делаю неправильно. Я пытаюсь решить весь этот день.
Я собираюсь разместить как можно больше кода, чтобы дать вам ребята столько деталей, сколько возможно.
Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь загрузить 3 дочерних представления после входа в систему. после входа в систему я могу видеть, что все 3 дочерние представления отображаются в моем инспекторе инструментов html, но частично отображаются в представлении браузера. По результатам исследования, я думаю, что моя проблема в том, что мне нужно использовать свойство "разрешить", чтобы дождаться завершения всех моих шаблонов и http до перехода на следующую страницу после входа в систему.
это страница входа в систему
<ion-view view-title="login">
<ion-content class="padding has-header">
<div class="row">
<div class="col col-50 col-offset-25">
<div class="card">
<div class="item item-text-wrap">
<form ng-submit="processForm()">
<div class="list">
<label class="item item-input">
<input type="text" placeholder="First Name" ng-model="formData.AccessKey" required="true">
</label>
<label class="item item-input">
<input type="text" placeholder="Last Name" ng-model="formData.Password" required="true">
</label>
</div>
<button class="button button-full button-positive">
Sign me in
</button>
</form>
</div>
</div>
</div>
</div>
</ion-content>
это мое приложение js, ответственное за всю маршрутизацию
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider){
$ionicConfigProvider.views.transition('none')
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login',{
url: '/',
templateUrl: 'templates/login.html',
controller:'loginController'
})
.state('main', {
url: '/main',
templateUrl: 'templates/main.html',
abstract: true
})
.state('main.panels', {
views: {
'ticketsPanel': {
templateUrl: 'templates/ticketsPanel.html'
},
'productsPanel': {
templateUrl: 'templates/productsPanel.html'
},
'categoriesPanel': {
templateUrl: 'templates/categoriesPanel.html',
controller: 'categoriesController'
}
}
})
})
это мои услуги
angular.module('starter.services', [])
.factory('Authentication', function($http, $q){
var deferred = $q.defer();
return {
login: function(formData) {
$http({
method : 'GET',
url : 'http://localhost:8888/employees/login',
params : formData
})
.success(function(respond){
deferred.resolve(respond);
})
},
getEmployee: function () {
return deferred.promise;
}
}
})
.factory('Categories', function($http){
//get the company id so i can get all the categories belong to that company
var CompanyId = JSON.parse(localStorage.getItem('employee'));
CompanyId = CompanyId[0].CompanyId;
return {
getCategories : function() {
$http({
method : 'GET',
url : 'http://localhost:8888/Categories/ajax_getCompaniesCategories',
params : {CompanyId: CompanyId}
})
.success(function(respond){
localStorage.setItem('categories', JSON.stringify(respond));
})
}
}
})
это мой контроллер
angular.module('starter.controllers', [])
.controller('loginController', function($scope, Authentication, $log, $state){
$scope.formData = {};
$scope.processForm = function(){
Authentication.login($scope.formData);
var promise = Authentication.getEmployee();
promise.then(function(respond){
localStorage.setItem('employee', JSON.stringify(respond));
$state.go('main.panels');
})
}
})
.controller('categoriesController', function($scope, Categories){
console.log('categories controller')
Categories.getCategories();
$scope.categories = JSON.parse(localStorage.getItem('categories'));
})
Извините, я обычно стараюсь только опубликовать немного кода, но я в отчаянии. Заранее спасибо.
Это не совсем понятно о ваших шаблонах, отображаемых пополам... Почему вы уверены, что у вас есть правильная разметка для них?
Однако ваш код не должен работать. Вы полностью перепутали обещания обработки. Лучше прочитать более об этом.
Я опубликую только код, который нужно изменение:
Не заверните существующие обещания в отложенные. Не стесняйтесь возвращать обещание. Помните, что обещания должны работать в цепочке. Т.е. promise.then().then()
также обещание, и вы можете прикрепить .then
к нему после того, как он был возвращен из функции.
.factory('Authentication', function ($http) {
return {
login: function (formData) {
return $http({
method: 'GET',
url: 'http://localhost:8888/employees/login',
params: formData
});
}
//also you don't need any extra functions to return the http response
//getEmployee was redundant
}
})
То же самое относится к службе Categories
.
Также сервис в этом случае не должен знать о бизнес-логике приложения - где взять companyId
. Он должен получить эту информацию в качестве параметра. Не шоу, а хорошая практика.
.factory('Categories', function ($http) {
return {
getCategories: function (companyId) {
//return the promise $http().success()
return $http({
method: 'GET',
url: 'http://localhost:8888/Categories/ajax_getCompaniesCategories',
params: {
CompanyId: CompanyId
}
})
.success(function (respond) {
localStorage.setItem('categories', JSON.stringify(respond));
//this will be parameter of next '.then' handler
return respond;
})
}
}
})
Теперь в контроллере мы используем его следующим образом
$scope.processForm = function(){
Authentication.login($scope. formData)
.then(function(respond){
localStorage.setItem('employee', JSON.stringify(respond));
$state.go('main.panels');
})
}
И в categoriesController
вы пытались использовать localStorage.getItem('categories')
до асинхронной операции завершена. Таким образом, он всегда был пустым. Вы должны подождать, пока это не будет сделано, и почему существуют обещания. В .then
работу обработчика завершение, однако из - за правильное возвращение из getCategories
последнего .then
обработчик нам не нужно, чтобы получить элемент из LocalStorage и разобрать его. Мы получаем объект как аргумент обработчика!
.controller('categoriesController', function ($scope, Categories) {
//good practice: controller is a proper place to retrieve id for request
var company = JSON.parse(localStorage.getItem('employee'));
var companyId = CompanyId[0].CompanyId;
Categories.getCategories(companyId)
.then(function (categories) {
//at this moment localStorage.getItem('categories') is already populated
//it can be used for later. At the moment we get categories as an argument
$scope.categories = categories;
})
})
Надеюсь это поможет
В конкретном маршруте, который вы вызываете, вы можете добавить:
.state('route', {
templateUrl: 'url/to/template.html',
resolve: {
myCategories: function(Categories) {
return Categories.getCategories();
}
}
})
И в вашем контроллере вы можете пройти в myCategories
следующим образом:
.controller('categoriesController', function($scope, myCategories){
$scope.categories = JSON.parse(myCategories);
})
Измените фабрику, чтобы вернуть значение ответа вместо использования localStorage:
.factory('Categories', function($http){
//get the company id so i can get all the categories belong to that company
var CompanyId = JSON.parse(localStorage.getItem('employee'));
CompanyId = CompanyId[0].CompanyId;
return {
getCategories : function() {
$http({
method : 'GET',
url : 'http://localhost:8888/Categories/ajax_getCompaniesCategories',
params : {CompanyId: CompanyId}
})
.success(function(respond){
return respond;
})
}
}
})
Маршрут будет ждать разрешения, прежде чем продолжить. Если решение не удастся, также будет маршрут.
Дайте мне знать, если это поможет или вам нужно больше деталей.