Получите данные из AJAX перед загрузкой AngularJS ap

Мы готовимся к обновлению нашего приложения AngularJS и рефакторингу для этого. В настоящее время мы столкнулись с архитектурной проблемой:

В настоящее время наше приложение загружает JSON через вызов jQuery AJAX, он устанавливает все данные, а затем загружает приложение.

Однако нам нужно переместить вызов AJAX в Angular, чтобы мы могли загружать приложение, не дожидаясь возврата AJAX (что необходимо для обновления).

$.get('/ajax/init').done(function (initData) {
  walletApp.run([
    'SomeService', function (someService) {
      // ...
    },
  ]);

  walletApp.config([
    'SomeProvider', function (someProvider) {
      // ...
    },
  ]);

  walletApp
    .factory('navInfo', function () {
      return initData.navInfo;
    })
    .factory('userInfo', function () {
      return initData.userInfo;
    });

  // ETC

  // Below is the important line
  angular.bootstrap(document, ['walletApp']);
});

Я пробовал что-то вроде приведенного ниже, где initService получает фид JSON, а затем назначает все данные

angular.module('walletApp')
  .run([
    'InitService', function (initService) {
      initService.get();
    },
  ]);

angular.bootstrap(document, ['walletApp']);

Но это приводит к множеству проблем.

Как правильно загрузить приложение AngularJS, которому для работы требуются данные от AJAX?


person Richard    schedule 22.02.2019    source источник
comment
Вы используете $http и делаете запрос? Если я правильно понимаю, вы хотите загрузить JSON данные перед загрузкой сайта. Пожалуйста подтвердите   -  person Shashank Vivek    schedule 22.02.2019
comment
Привет, @ShashankVivek, я использую this.$http.get<any>(url, {params: params}). Да, данные AJAX необходимы для настройки фабрик и других данных.   -  person Richard    schedule 22.02.2019
comment
проверьте мой ответ, это то, что вы ищете? или вы можете загрузить сайт, а затем настроить данные, показывая счетчик до завершения вызова? Сообщите мне свой отзыв, чтобы я мог предложить лучшее решение   -  person Shashank Vivek    schedule 22.02.2019
comment
При загрузке AJAX можно использовать счетчик, если мы можем вызывать angular.bootstrap, не зависящий от завершения вызова AJAX.   -  person Richard    schedule 22.02.2019


Ответы (1)


Хорошо, насколько я понимаю, вам нужны данные json до того, как загрузится что-либо еще из пользовательского интерфейса (поскольку это данные, которые требуются до того, как сайт загрузится).

Таким образом, вы не можете сделать http на этапе конфигурации, и если вы вызываете run фазу, вам нужно дождаться выполнения основного http вызова (назовем его /site_data/).

  1. Не используйте ng-app в index.html

  2. В app.js файле

    (function() {
    
    var initInjector = angular.injector(['ng']);
    var $http = initInjector.get('$http');
    $http.get('/site_data/',{headers: {'Cache-Control' : 'no-cache'}}).then(
        function (response) {
            angular.module('walletApp.info', []).constant('SITE_CONF_DATA', response.data);
    
            angular.element(document).ready(function() {
                angular.bootstrap(document, ['walletApp']); //<--  manual bootstrapping of `ng-app`
            });
        }
      );
    })();
    
    var app = angular.module('walletApp',['walletApp.info']);
    app.config(function(SITE_CONF_DATA){
       // Bingo, you have the data
    })
    
    app.run().....
    
    app.controller...
    
    app.factory.....
    

У этого подхода есть недостаток, заключающийся в том, что ваш сайт будет загружен после разрешения вызова http.

Обновлять

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

  ngOnInit() {
    // Ensure AngularJS is only bootstrapped once.
    if (!angularJsBootstrapped) {
      this.http.get('https://jsonplaceholder.typicode.com/todos/1').delay(5000).subscribe(res => {
        angular.module('data',[]).constant('DATA',res);
        this.upgrade.bootstrap(document.body, [module.name]);
        setUpLocationSync(this.upgrade);
        angularJsBootstrapped = true;
      })
    }
  }

Я создал constant, создав модуль после разрешения http, а затем вручную загрузил модуль angularJS.

angular.module('data',[]).constant('DATA',res);

Что-то подобное может быть полезно в описываемой вами ситуации.

person Shashank Vivek    schedule 22.02.2019
comment
Спасибо! Однако мы не можем использовать это решение, поскольку angular.bootstrap вызывается внутри обратного вызова запроса AJAX. Мы заняты обновлением Angular до версии 6, и загрузка приложения должна происходить из кода Angular 6. Таким образом, он не знает, завершился ли AJAX. Это решение в основном такое же, как и у меня, но с использованием AngularJS вместо jQuery для загрузки данных. - person Richard; 22.02.2019
comment
вы планируете набрать angularjs код из angular 6 кода? - person Shashank Vivek; 22.02.2019
comment
v6.angular.io/guide/upgrade#bootstrapping-hybrid-applications - this.upgrade.bootstrap (document.body, ['heroApp'], {strictDi: true}) ;. При обновлении через гибридное приложение AngularJS загружается через Angular. - person Richard; 22.02.2019
comment
@ Ричард: Спасибо за замечательный вопрос. Я придумал решение и представил его в качестве демонстрации. Дайте мне знать, может ли он сейчас дать вам ответ. :) - person Shashank Vivek; 23.02.2019
comment
@ Ричард: ты нашел какое-нибудь решение? - person Shashank Vivek; 01.04.2019
comment
Пока нет, в настоящее время мы рассматриваем другие решения, мы, вероятно, будем внедрять JSON непосредственно в HTML, поэтому нам не нужно получать его при загрузке страницы. Спасибо за продолжение! - person Richard; 01.04.2019