Angularjs индивидуальное выполнение процесса

0

Хотелось бы проверить, что у меня есть простая функция запроса ресурса веб-сервисов

//Get country lists
$scope.getCountry = function(){
    $http({
        method  : 'GET',
        url     : cdnLinks('country'),
    }).success(function(data) {
        $scope.countries = data;
    }).error(function(data) {
        console.log(data);
    });
};

//Get profile 
$scope.getProfile = function(profile_id, select){
     var formatJSON = {
            profile_id: profile_id,
            select: select,
        };
    var json = JSON.stringify(formatJSON);
    var urlsafe = exEncrypt(json);
    ProfileService.profileActions.query({payload:urlsafe}).$promise.then(function(datas){
        $scope.uProfile = datas[0];
        document.querySelector('title').innerHTML = $scope.uProfile.username;
    });  
};

//Initialize update sequence
$scope.initUpdate = function(profile_id, select){
    $scope.getCountry();
    $scope.getProfile(profile_id, select);
}

Итак, что делает код, пользователь нажимает кнопку "Обновить", он ng-click="initUpdate(param1, param2)" которая затем загружает все и отображает необходимую информацию пользователю. Эта функция работает отлично, но есть одна проблема. Поскольку getCountry() обычно возвращает больший размер файла [~ 3 - 3,5 кбайт, время загрузки ~ 260 ++ мс зависит от сервера] сравнивается с простым getProfile() [~ 1 - 2kb, время загрузки ~ 200 ++ ms зависит от сервера ], то, что делает код, будет отображаться профиль до того, как будет загружен список стран, который на странице пользовательского интерфейса оказался заполненным пустым полем.

Итак, что я getProfile() изначально, применяя тайм-аут к getProfile() как это

$scope.initUpdate = function(profile_id, select){
    $scope.getCountry();
    $timeout(function(){
        $scope.getProfile(profile_id, select);
    }, 200);
}

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

Я хотел бы проверить, есть ли какой-либо подход, который я могу использовать/реализовать таким образом, чтобы я хотел

  1. Все необходимые ресурсы для загрузки и ЗАВЕРШЕНИЯ (getCountry(), getInterest(), getABCDEFG() и некоторые другие...)
  2. getProfile() только getProfile()?
Теги:

2 ответа

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

Вы можете использовать обещания (https://docs.angularjs.org/api/ng/service/ $ q) для этого. Добавьте $ q к вашему контроллеру, а затем мы обещаем в getCountry() и initUpdate().

Он будет ожидать, когда запрос getCountry() будет завершен, прежде чем продолжить. Более того, если вы хотите добавить другие запросы, вы можете использовать $ q.all(), чтобы дождаться завершения нескольких запросов перед отображением профиля.

$scope.initUpdate = function(profile_id, select){
    $scope.getCountry().then(
        function(){
            $scope.getProfile(profile_id, select);
        }
    );
}

$scope.getCountry = function(){
    var deferred = $q.defer();
    $http({
        method  : 'GET',
        url     : cdnLinks('country'),
    }).success(function(data) {
        $scope.countries = data;
        deferred.resolve();
    }).error(function(data) {
        console.log(data);
        deferred.reject();
    });

    return deferred.promise;
};

(Примечание. Возможно, вы сможете улучшить код, вернув $ http prom напрямую)

  • 2
    Я полностью согласен с тем фактом, что $ http уже возвращает обещание, либо с успехом / ошибкой, либо потом, и что это не оптимально. Я просто пишу четкий код. Мой пример верный, и каждый может понять / улучшить его. $ q действительно для асинхронного JS. Период. Это не имеет ничего общего с длительной загрузкой или мобильным использованием. Просто используйте его, если вам нужен асинхронный код, который сейчас почти необходим для каждого хорошего приложения JS. Вы должны прочитать страницу $ q. В подзаголовке четко сказано: «Служба, которая помогает асинхронно запускать функции и использовать их возвращаемые значения (или исключения) после завершения обработки».
  • 0
    В этот момент способ решения noKid решил мою проблему. Я позволю ему работать, а также попробую решение @Okazari, так как это потребует от меня перепроектирования определенной части модуля. Но в любом случае оба решения решают мою проблему ... Единственная проблема заключается в том, что подход Оки потребует серьезных изменений в других моих зависимых модулях ... Приветствия ...
Показать ещё 2 комментария
2

Вы можете просто отобразить некоторые загрузчики на тех частях, которые не должны отображаться.

Создайте boolean var, чтобы скрыть/показать загрузчика, если вызов ожидает или нет.

Если вы хотите загрузить некоторые вещи перед загрузкой представления, вы можете посмотреть на ui-router и его свойства разрешения.

Вы также можете вернуть вызов $ http в своих функциях, чтобы вы могли справиться с ним так, как хотите. (Например, их цепочка).

//Get country lists
$scope.getCountry = function(){
    return $http({
        method  : 'GET',
        url     : cdnLinks('country'),
    });
};

//Get profile 
$scope.getProfile = function(profile_id, select){
     var formatJSON = {
            profile_id: profile_id,
            select: select,
        };
    var json = JSON.stringify(formatJSON);
    var urlsafe = exEncrypt(json);
    return ProfileService.profileActions.query({payload:urlsafe}).$promise  
};

//Initialize update sequence
$scope.initUpdate = function(profile_id, select){
    $scope.getCountry().success(function(data) {
        $scope.countries = data;
        $scope.getProfile(profile_id, select).then(function(datas){
           $scope.uProfile = datas[0];
           document.querySelector('title').innerHTML = $scope.uProfile.username;
        });
    }).error(function(data) {
        console.log(data);
    });
}

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

Надеюсь, что это помогло, если у вас возникнет вопрос (особенно о ui-router), не стесняйтесь спрашивать.

РЕДАКТИРОВАТЬ:

Обратите внимание, что обычно $ http-вызовы не устанавливаются в контроллер, а в службу.

Ниже приведен пример определения состояния (из ui-router) с помощью разрешений:

$stateProvider
  .state('mystate', {
    url: "myroute"
    templateUrl: 'template.html',
    controller: "mystateController",
    resolve : {
        countries : function($http){
                           return $http({
                           method  : 'GET',
                           url     : cdnLinks('country'),
                        });
                    }
    }
  })

Вы сможете ввести параметр разрешения в свой контроллер:

app.controller('mystateController', function(countries) {
  //Here goes your countries.
  console.log(countries);
});

Ещё вопросы

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