Получите данные из AJAX перед загрузкой приложения AngularJS - PullRequest
0 голосов
/ 22 февраля 2019

Мы готовимся к обновлению нашего приложения 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 для работы?

1 Ответ

0 голосов
/ 22 февраля 2019

Хорошо, насколько я понимаю, вам нужны данные 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);

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

...