Angular2:使用Elasticsearch Client绑定数据

Angular 2: Binding Data using Elasticsearch Client

我正在尝试使用 Angular 2 和来自 npm 的官方 elasticsearch.js 客户端为 Elasticsearch 编写一个简单的 Web 界面。

我创建了这样的服务:

import { Injectable } from '@angular/core';
import { Client } from 'elasticsearch';

@Injectable()
export class ElasticsearchService {

    private _client: Client;
    constructor() {
        if (!this._client) {
            this._connect();
        }
    };
    private _connect() {
        this._client = new Client({
            host: 'http://my-elasticsearch-host:9200',
            log: 'trace'
        });
    };
    isAvailable(): PromiseLike<String> {
        return this._client.ping({
            requestTimeout: Infinity
        });
    }
}

这似乎工作正常。日志显示请求已得到正确回答。

这是我的组件:

import { OnInit, Component } from '@angular/core';
import { ElasticsearchService } from './services/elasticsearch.service';

@Component({
    selector: 'foo',
    templateUrl: './foo.component.html',
    providers: [ElasticsearchService]
})
export class TimeLineComponent implements OnInit {

    private status: String = 'not ok';
    constructor(private esService: ElasticsearchService) { } ;

    ngOnInit(): void {
        this.showStatus();
    }

    showStatus(): void {
        this.esService.isAvailable()
            .then( response => this.status = 'OK' );
    }

}

这是模板:

status:{{status}}

我不明白为什么我的浏览器一直显示 "not ok"。我在这里错过了什么?

我认为视图不刷新的原因是 elasticsearch 客户端使用它自己的 deferred/promise 实现,Zone.js 没有采用它。

我找到了两个可能的解决方案:

1:设置组件变量后

2:替换客户端默认的defer方法。幸运的是,这很容易(我从 elasticsearch.jquery.js 那里偷走了这个想法)

function defer() {
  let resolve, reject, promise;

  promise = new Promise((_resolve, _reject) => {
    resolve = _resolve;
    reject = _reject;
  });

  return { resolve, reject, promise };
}

this.client = new Client({
  host: 'http://my-elasticsearch-host:9200',
  log: 'trace',
  defer: defer
});

因为这是使用标准的 Promise class,它被 Zone 正确拾取。

我仍在测试 defer() 的这种简约替代是否足够,但它可能需要额外的方法。如果出现问题,我会 post 更新。