我之前发过这个问题,老实说,我不知道我做错了什么。我一直试图解决这个问题。
我将发布尽可能多的代码,以尽可能多地为您提供详细信息。
我遇到的问题是我在登录后尝试加载3个子视图。 登录后,我可以在我的html工具检查器中看到所有3个子视图渲染,但在浏览器视图中有部分渲染。经过研究,我认为我的问题是我需要使用一个名为resolve的属性来等待我的所有模板和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>
这是我的app 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'));
})
抱歉,我通常只尝试发布一些代码,但我很绝望。 提前谢谢。
答案 0 :(得分:1)
您的模板显示为一半并不十分清楚......为什么您确定自己有正确的标记?
但是你的代码不适用。你完全搞砸了处理承诺。你最好先阅读more。
我只会发布应该更改的代码:
不要将现有的承诺包装成延期。不要犹豫,回复诺言。请记住,承诺应该在链条中起作用。即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;
})
})
希望这有帮助
答案 1 :(得分:0)
在您呼叫的特定路线中,您可以添加:
/root
在你的控制器中,你可以像这样传递/home/<yourLogin>/.ssh
:
.state('route', {
templateUrl: 'url/to/template.html',
resolve: {
myCategories: function(Categories) {
return Categories.getCategories();
}
}
})
更改工厂以返回响应值,而不是使用localStorage:
myCategories
在继续之前,路线将等待决定返回。如果解决方案失败,路线也将失败。
如果这有帮助或者您需要更多细节,请告诉我。