ui路由器解决问题

时间:2015-07-05 03:04:55

标签: javascript html angularjs

我之前发过这个问题,老实说,我不知道我做错了什么。我一直试图解决这个问题。

我将发布尽可能多的代码,以尽可能多地为您提供详细信息。

我遇到的问题是我在登录后尝试加载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'));

})

抱歉,我通常只尝试发布一些代码,但我很绝望。 提前谢谢。

2 个答案:

答案 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

在继续之前,路线将等待决定返回。如果解决方案失败,路线也将失败。

如果这有帮助或者您需要更多细节,请告诉我。