如何在同一个Angular 6组件中的另一项服务中使用从一项服务接收的值?

时间:2018-11-30 21:23:31

标签: javascript angular

以下组件的代码来自我正在创建的Angular 6 Web应用程序。该应用程序显示具有CRUD功能的表。我有一个名为GetDBValuesService的Angular服务,该服务已连接到数据库并使用DBValues()来检索数组数组(每个内部数组都包含数据库中给定行的值)。然后,我的代码收集了“数字”属性等于10的行。这些行然后由我的EventEmitter数据项使用,这使它们可以显示在我的网页的CRUD表中。

我创建了另一个名为DataService的Angular服务,该服务从另一个组件接收一个整数值,并将该值发送到所示的组件(在订阅之后)。我在以下代码中订阅了此服务,并让gotdata实例(在此组件中声明了一个公共var)接收该服务的值。但是,当我尝试在该订阅之外使用该实例(以替换上述的硬编码10)时,this.gotdata是未定义的。

如何修改代码,以便可以在GetDBValuesService服务中使用DataService服务提供的值?目前,由于采用了硬编码10,因此以下代码可以正常工作,但是如果我删除了该行,则无效。感谢您抽出时间来阅读。

这是我的CRUD组件的一部分:

refresh = () => {
    this.DataService.DataID$.subscribe((data) => {
        this.gotdata = data;
        console.log(this.gotdata); //10 (value from console)
    });
    console.log(this.gotdata); //undefined (value from console)
    this.gotdata = 10; //hardcoded value allows further functionality, will be removed when this.gotdata retains its value from the above subscription
    if (this.gotdata != null) {
        this.GetDBValuesService.DBValues().subscribe((result) => {
            var a = 0;
            for (var i = 0; i < result.length; i++) {
                if (result[i].Number == this.gotdata) {
                    this.info[a] = result[i];
                    a = a + 1;
                }
            }
            this.dataItems.next(this.info); //sets rows to be displayed in the web page's table (used by component's HTML file)
        });
    }}

2 个答案:

答案 0 :(得分:0)

this.gotdata未定义,因为尚未解析数据。

refresh = () => {
this.DataService.DataID$.subscribe((data) => {
    this.gotdata = data;
    console.log(this.gotdata); //10 (value from console)

    if (this.gotdata != null) {
        this.GetDBValuesService.DBValues().subscribe((result) => {
            var a = 0;
            for (var i = 0; i < result.length; i++) {
                if (result[i].Number == this.gotdata) {
                    this.info[a] = result[i];
                    a = a + 1;
                }
            }
            this.dataItems.next(this.info); //sets rows to be displayed in the web page's table (used by component's HTML file)
        });
   }}
});

或者您可以将其放入完整回调中的订阅中:

this.service.subscribe((data) => {
    // code here
},
(error) => console.error(error),
() => {
    // do stuff.
});

答案 1 :(得分:0)

问题在于,当您调用console.log(...)和下面的代码时,来自dataID$观察对象的数据仍在传送给您。 (Why do u need to work with observables?

最好的方法是使用RXJS switchMap运算符(what is switchMap?)。因为如我所见,您要订阅第一个observable,然后再订阅另一个observable。所以可以这样:

refresh = () => {
    this.DataService.DataID$.pipe(switchMap(data: any) => {
        if (data) {
            this.gotdata = data;
            return this.GetDBValuesService.DBValues();
        } else {
            return of(null); // if 'data' are null, return "empty" observable
        }
    })).subscribe((result: any) => {
        if (!result) {
            return; // return if 'result' is null (so the code bellow won't be executed)
        }
        var a = 0;
        for (var i = 0; i < result.length; i++) {
            if (result[i].Number == this.gotdata) {
                this.info[a] = result[i];
                a = a + 1;
            }
        }
        this.dataItems.next(this.info);
    });