【问题标题】:Get data from AJAX before loading AngularJS ap在加载 AngularJS ap 之前从 AJAX 获取数据
【发布时间】:2019-02-22 12:40:40
【问题描述】:

我们正在准备升级我们的 AngularJS 应用程序并为此进行重构。目前我们遇到了一个架构问题:

我们的应用当前通过 jQuery AJAX 调用加载 JSON,这会设置所有数据,然后引导应用。

但是,我们需要将 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']);

但这会导致一系列问题。

我们如何正确加载需要来自 AJAX 的数据才能运行的 AngularJS 应用程序?

【问题讨论】:

  • 您是否在使用$http 并提出请求?如果我的理解是正确的,那么您想在加载站点之前加载 JSON 数据。请确认
  • 嗨@ShashankVivek,我正在使用this.$http.get<any>(url, {params: params})。是的,AJAX 数据是设置工厂和其他数据所必需的。
  • 检查我的答案,这是您要找的吗?或者您可以加载网站,然后在显示微调器的同时设置数据,直到通话完成?让我知道您的反馈,以便我提供更好的解决方案
  • 在 AJAX 加载时使用微调器就可以了,只要我们可以调用 angular.bootstrap 而无需依赖 AJAX 调用即可完成。

标签: angularjs typescript angular-upgrade


【解决方案1】:

好的,根据我的理解,在加载任何其他 UI 之前,您需要 json 数据(因为它是在网站加载之前需要的数据)。

所以,您不能在配置阶段拨打http,如果您在run 阶段拨打电话,您必须等到主要的http 拨打电话(我们称之为/site_data/)。

  1. 不要在 index.html 中使用ng-app

  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 调用,您的网站就会被加载。

更新

根据 cmets,您正在尝试构建一个混合应用程序,所以 take a look at this demo

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

我通过在解析http 后创建一个模块创建了一个constant,然后我手动引导了angularJS 模块。

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

这样的事情可能对您所描述的情况有所帮助。

【讨论】:

  • 谢谢!但是我们不能使用这个解决方案,因为 angular.bootstrap 在 AJAX 请求的回调中被调用。我们正忙于将 Angular 升级到版本 6,并且应用程序的引导需要从 Angular 6 代码中进行。所以它不知道AJAX是否已经完成。这个解决方案和我已经有的基本一样,但是使用 AngularJS 而不是 jQuery 来加载数据。
  • 您打算从angular 6 代码调用angularjs 代码?
  • v6.angular.io/guide/upgrade#bootstrapping-hybrid-applications - “this.upgrade.bootstrap(document.body, ['heroApp'], { strictDi: true });”。通过混合应用程序升级时,AngularJS 通过 Angular 进行引导
  • @Richard :感谢这个很棒的问题。我想出了一个解决方案,并将其作为演示提供。让我知道它现在是否可以为您解答。 :)
  • @Richard:你找到解决办法了吗?
猜你喜欢
  • 1970-01-01
  • 2015-02-17
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多