【问题标题】:How do you substitute HttpClient in Aurelia?你如何在 Aurelia 中替换 HttpClient?
【发布时间】:2016-05-10 12:07:39
【问题描述】:

我是 Aurelia 的新手。

您将如何更改以下代码以提供虚拟 HttpClient,例如一个 json 阅读器,它只提供一组静态的 json 数据,无需开发中的服务器。

import {inject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-fetch-client';

@inject(HttpClient)
export class Users {
  heading = 'Github Users';
  users = [];

  constructor(http) {
    http.configure(config => {
      config
        .useStandardConfiguration()
        .withBaseUrl('https://api.github.com/');
    });

    this.http = http;
  }

  activate() {
    return this.http.fetch('users')
      .then(response => response.json())
      .then(users => this.users = users);
  }
}

【问题讨论】:

    标签: javascript json aurelia


    【解决方案1】:

    需要几个步骤才能使您原始帖子中的演示代码达到我们可以替代 HttpClient 实现的状态。

    第一步

    删除类的构造函数中的配置代码...

    这些行:

    users.js

    ...
    http.configure(config => {
      config
        .useStandardConfiguration()
        .withBaseUrl('https://api.github.com/');
    });
    ...
    

    应移至main.js 文件:

    ma​​in.js

    export function configure(aurelia) {
      aurelia.use
        .standardConfiguration()
        .developmentLogging();
    
      configureContainer(aurelia.container);  // <--------
    
      aurelia.start().then(a => a.setRoot());
    }
    
    function configureContainer(container) {
      let http = new HttpClient();
      http.configure(config => {
        config
          .useStandardConfiguration()
          .withBaseUrl('https://api.github.com/');
      });
      container.registerInstance(HttpClient, http); // <---- this line ensures everyone that `@inject`s a `HttpClient` instance will get the instance we configured above.
    }
    

    现在我们的 users.js 文件应该如下所示:

    users.js

    import {inject} from 'aurelia-framework';
    import {HttpClient} from 'aurelia-fetch-client';
    
    @inject(HttpClient)
    export class Users {
      heading = 'Github Users';
      users = [];
    
      constructor(http) {
        this.http = http;
      }
    
      activate() {
        return this.http.fetch('users')
          .then(response => response.json())
          .then(users => this.users = users);
      }
    }
    

    第 2 步:

    模拟 HttpClient。

    user.js 模块仅使用fetch 方法,该方法返回一个Response 对象,该对象具有json 方法。这是一个简单的模拟:

    let mockUsers = [...todo: create mock user data...];
    
    let httpMock = {
      fetch: url => Promise.resolve({
        json: () => mockUsers
      })
    };
    

    第 3 步:

    重新配置容器以使用 http mock:

    在步骤 1 中,我们向 main.js 模块添加了一个 configureContainer 函数,该模块在容器中注册了一个配置的 HttpClient 实例。如果我们想使用我们的模拟版本,configureContainer 函数将更改为:

    ma​​in.js

    ...
    
    let mockUsers = [...todo: create mock user data...];
    
    let httpMock = {
      fetch: url => Promise.resolve({
        json: () => mockUsers
      })
    };
    
    function configureContainer(container) {      
      container.registerInstance(HttpClient, httpMock);
    }
    

    在此处配置容器的更多信息:https://github.com/aurelia/dependency-injection/issues/73

    【讨论】:

    • 太棒了,@jdanyow :)
    【解决方案2】:

    还有另一种可能性,可以在开发过程中为应用程序提供静态数据。 Navigation Skeleton 已经带有 Gulp 和 BrowserSync,所以我们用它们来伪造 API 调用。

    假设您从 /api 虚拟目录加载 JSON 数据,例如

    GET /api/products
    

    在这种情况下,你只需要两件事来伪造它。

    将您的模拟数据放入文件中

    转到您的 Aurelia 应用程序的根文件夹并创建一个 /api 文件夹。

    创建一个/api/products 子文件夹并放置一个名为GET.json 的新文件。此文件应包含 JSON,例如

    GET.json

    [ { "id": 1, "name": "Keyboard", "price": "60$" },
      { "id": 2, "name": "Mouse", "price": "20$" },
      { "id": 3, "name": "Headphones", "price": "80$" }
    ]
    

    配置 BrowserSync 以模拟您的 API 调用

    导航到/build/tasks 文件夹并编辑serve.js 文件。将服务任务的定义改为如下代码:

    gulp.task('serve', ['build'], function(done) {
      browserSync({
        online: false,
        open: false,
        port: 9000,
        server: {
          baseDir: ['.'],
          middleware: function(req, res, next) {
            res.setHeader('Access-Control-Allow-Origin', '*');
    
            // Mock API calls
            if (req.url.indexOf('/api/') > -1) {
              console.log('[serve] responding ' + req.method + ' ' + req.originalUrl);
    
              var jsonResponseUri = req._parsedUrl.pathname + '/' + req.method + '.json';
    
              // Require file for logging purpose, if not found require will 
              // throw an exception and middleware will cancel the retrieve action
              var jsonResponse = require('../..' + jsonResponseUri);
    
              // Replace the original call with retrieving json file as reply
              req.url = jsonResponseUri;
              req.method = 'GET';
            }
    
            next();
          }
        }
      }, done);
    });
    

    现在,当您运行 gulp serve 时,BrowserSync 将处理您的 API 调用并从磁盘上的静态文件中提供它们。

    您可以在我的github repo 中查看示例,在我的Mocking API calls in Aurelia 中查看更多说明。

    【讨论】:

    • 如果您的 api 调用将转到外部站点,这种方法是否有效?
    猜你喜欢
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    相关资源
    最近更新 更多