Angular2 Observable Rxjs如何调用私有函数

时间:2017-09-20 22:51:30

标签: angular rxjs rxjs5

好的,我是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不是函数

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

谢谢,

2 个答案:

答案 0 :(得分:2)

这里的问题是这个谜题的不同部分如何处理this。 Typescript编译器将生成以下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 的上下文中执行此操作通过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变量,并将其用于调用extractItems()内的extractFeeds()函数。这样,代码的Typescript版本中的this指针始终指向extractFeeds()函数内的组件实例,无论{j}代码中的this指向何处。< / p>

所有其他以相同方式调用的函数也是如此,例如,代码中的handleError。

您可以在Typescript here中找到this问题的非常详细的解释。

答案 1 :(得分:0)

问题源于“这个”背景。当试图使用this.extractItems()时,'this'的上下文在observable而不是class中。

尝试这样的事情:

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

您可能还需要从rxjs导入。

通过使用箭头符号,您将没有可观察的“this”上下文,并且该类中的调用方法将起作用。