UI роутер разрешает проблемы

0

Я опубликовал этот вопрос раньше, и я честно не знаю, что я делаю неправильно. Я пытаюсь решить весь этот день.

Я собираюсь разместить как можно больше кода, чтобы дать вам ребята столько деталей, сколько возможно.

Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь загрузить 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'));

})

Извините, я обычно стараюсь только опубликовать немного кода, но я в отчаянии. Заранее спасибо.

2 ответа

1
Лучший ответ

Это не совсем понятно о ваших шаблонах, отображаемых пополам... Почему вы уверены, что у вас есть правильная разметка для них?

Однако ваш код не должен работать. Вы полностью перепутали обещания обработки. Лучше прочитать более об этом.

Я опубликую только код, который нужно изменение:
Не заверните существующие обещания в отложенные. Не стесняйтесь возвращать обещание. Помните, что обещания должны работать в цепочке. Т.е. 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;
            })
})

Надеюсь это поможет

0

В конкретном маршруте, который вы вызываете, вы можете добавить:

.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;
        })
    }
}
})

Маршрут будет ждать разрешения, прежде чем продолжить. Если решение не удастся, также будет маршрут.

Дайте мне знать, если это поможет или вам нужно больше деталей.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню