Angular2 Observable Rxjs如何调用私有函数

Angular2 Observable Rxjs how to call private function

好的,我是 RxJs 的新手,今天被介绍了..所以这是一个完全新手的问题。

我的用例是提取 XML RSS 提要并将它们转换为 JSON 提要。

我有一个 FeedService 具有以下内容

getFeedContent(url: string) : Observable<Feed> {
    return this.http.get(url)
        .map(this.extractFeeds)
        .catch(this.handleError);
}

private extractFeeds(res: Response) {
    let content = res.text;
    let feed = this.extractItems(content);
    return feed ;
}

提取项是一个常规函数,它接收内容并进行 XML 解析以构建 json 对象。还有多种其他方法

这是代码

private extractItems(content) : Feed {
    console.log(content);
    let f = this.getFeedInfo(content);
    return {
        status: "ok",
        feed : f ,
        items: this.getItems(content.toString(), 'item')
                   .concat(this.getItems(content.toString(), 'entry'))
    }
}

我在 运行 此代码时遇到此错误:

feed.service.ts:144 this.extractItems is not a function

我可能将 Observables 与常规函数调用混合在一起,我需要帮助。 如何使用 XML 内容作为输入调用 extractItems。

谢谢,

问题源于 'this' 上下文。当尝试使用 this.extractItems() 时,'this' 的上下文在可观察范围内,而不是 class.

尝试这样的事情:

let extractFeeds = (res: Response) => {
    let content = res.text;
    let feed = this.extractItems(content);
    return feed;
}

您可能还需要从 rxjs 导入。

通过使用箭头表示法,您将没有 'this' 可观察上下文,class 中的调用方法将起作用。

这里的问题是 this 如何由这个拼图的不同部分处理。打字稿编译器将产生以下 javascript:

YourComponent.prototype.getFeedContent = function (url) {
    return this.http.get(url)
        .map(this.extractFeeds)
        .catch(this.handleError);
};
YourComponent.prototype.extractFeeds = function (res) {
    var content = res.text;
    var feed = this.extractItems(content);
    return feed;
};
YourComponent.prototype.extractItems = function (content) {
    console.log(content);
    var f = this.getFeedInfo(content);
    return {
        status: 'ok',
        feed: f,
        items: this.getItems(content.toString(), 'item')
            .concat(this.getItems(content.toString(), 'entry'))
    };
};

现在,此代码的主要警告是当 .map() 运算符调用 extractFeeds() 函数时,它是在 Observable[=46 的上下文中执行的=]this.http.get() 调用返回,不在您的组件 的上下文中。因此,在 extractFeeds() 函数中 this 指向那个 Observable,并且尝试调用 this.extractItems() 显然失败了,因为 Observable 上没有这样的方法。

因此,修复它实际上非常简单。您需要做的就是如下更改 extractFeeds() 声明:

getFeedContent(url: string): Observable<Feed> {
    return this.http.get(url)
        .map(this.extractFeeds)
        .catch(this.handleError);
}

private extractFeeds = (res: Response) => { // <-- using arrow syntax
    let content = res.text;
    let feed = this.extractItems(content);
    return feed ;
}

private extractItems(content) : Feed {
    console.log(content);
    let f = this.getFeedInfo(content);
    return {
        status: "ok",
        feed : f ,
        items: this.getItems(content.toString(), 'item')
                   .concat(this.getItems(content.toString(), 'entry'))
    }
}

这次 Typescript 编译器生成以下代码:

var YourComponent = (function () {
    function YourComponent(http) {
        var _this = this;
        this.http = http;
        this.extractFeeds = function (res) { // this is how it is defined now in JS
            var content = res.text;
            var feed = _this.extractItems(content);
            return feed;
        };
    }
    // ... rest declarations skipped
    return YourComponent;
}());

看到 TSC 在这里做了什么吗?它将对组件的引用保存到 _this 变量中,并用它来调用 extractFeeds() 中的 extractItems() 函数。这样,您代码的 Typescript 版本中的 this 指针将 始终 指向 extractFeeds() 函数内的组件实例,而不管 this 实际指向何处 javascript代码。

同样适用于以相同方式调用的所有其他函数,例如代码中的 handleError。

您可以在 Typescript here.

中找到对 this 问题的非常详细的解释