【问题标题】:Component interaction via service Angular 2通过服务 Angular 2 进行组件交互
【发布时间】:2017-01-23 17:17:13
【问题描述】:

我正在尝试这样做https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

interaction.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';    
import { Options } from './options';

@Injectable()
export class InteractionService {
    private optionsSource = new Subject<Options>();

    options$ = this.optionsSource.asObservable();

    setOptions(options: Options) {
        this.optionsSource.next(options);
    }
}

app.component.ts

import { Component, OnInit } from '@angular/core';
import { CoreService } from './core/core.service';
import { InteractionService } from './providers/interaction.service';
import { Options } from './options';

@Component({
    selector: 'app',
    templateUrl: './app/app.component.html'
})
export class AppComponent implements OnInit {
    constructor(private coreService: CoreService,
        private interactionService: InteractionService) { }

    ngOnInit() {
          this.coreService.getOptions().subscribe((options: Options) => { 
              this.interactionService.setOptions(options);
            });
        }
    }

sidebar.component.ts

import { Component, OnInit} from '@angular/core';
import { InteractionService } from './../../providers/interaction.service';
import { Options } from './options';

@Component({
    selector: 'app-sidebar',
    templateUrl: './app/core/sidebar/sidebar.component.html'
})
export class SidebarComponent implements OnInit {
    options: Options;

    constructor(private interactionService: InteractionService) {
        this.interactionService.options$.subscribe(
            (options: options) => {
                this.options = options;
            });
    }

    ngOnInit() {
        if (this.options.mode === "test") {
            //...
        } else {
            //...
        }
    }
}

app.component.html

<app-sidebar></app-sidebar>
<router-outlet></router-outlet>

并在app.module.ts中声明“providers: [InteractionService]”。

但在 sidebar.component.ts 中出现错误“无法读取未定义的属性 'mode'”。

我做错了什么?我该如何解决?

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    假设在调用ngOnInit() 时该值可用是不安全的。

    export class SidebarComponent implements OnInit {
        options: Options;
    
        constructor(private interactionService: InteractionService) {
            this.interactionService.options$.subscribe(
                (options: options) => {
                    this.options = options;
                    if (this.options.mode === "test") {
                      //...
                    } else {
                      //...
                    }
                });
        }
    }
    

    只有在调用传递给subscribe(...) 的回调时才可以安全地假设该值可用。如果您从对服务器的请求中获取值,这可能在构造函数或ngOnInit(或任何其他生命周期回调)被调用并完成后很长时间。

    【讨论】:

    • 你有什么建议?在 sidebar.component.ts 中执行与 app.component.ts 中相同的第二个 ajax 请求吗?我只想减少应用程序中的 ajax 请求数。
    【解决方案2】:

    您可以尝试做几件事:
    interaction.service.ts

    • 尝试使用 BehaviorSubject,例如 private optionsSource = new BehaviorSubject&lt;Options&gt;(null);

    希望,以上一行将使您的应用无需其他更改即可运行。但我们可以做得更好。

    app.component.ts

    • 尝试将订阅移动到 interaction.service.ts 的构造函数。

    然后,您将无法与 app.component 中的 interaction.service.ts 进行交互,这不是您正在做的——通过服务进行通信。别担心。

    sidebar.component.ts

    • 尝试将订阅从constructor 移至ngOnInit

    这是一个plnk,上面有修改供您参考。

    【讨论】:

      猜你喜欢
      • 2016-07-19
      • 2016-07-31
      • 2017-08-26
      • 2020-12-28
      • 2017-01-08
      • 2017-06-13
      • 2019-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多