通过服务Angular 2进行组件交互

时间:2017-01-23 07:57:43

标签: angular typescript

我试图这样做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>

并声明&#34; providers: [InteractionService]&#34;在 app.module.ts

但在 sidebar.component.ts 中我有错误&#34; 无法读取属性&#39;模式&#39;未定义的&#34;。

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

2 个答案:

答案 0 :(得分:1)

假设在调用public sealed partial class MainPage : Page { private ObservableCollection<Job> Jobs; public MainPage() { this.InitializeComponent(); Jobs = new ObservableCollection<Job>(); } private void Button1_Click(object sender, RoutedEventArgs e) { string newJson = @" [ {'job_id':399783,'job_number':'XYZ-J111111','ship_type':'c'}, {'job_id':445672,'job_number':'XYZ-J222222','ship_type':'p'}, {'job_id':896543,'job_number':'XYZ-J333333','ship_type':'f'} ]"; JArray result = JArray.Parse(newJson); for (int i = 0; i < result.Count; i++) { Jobs.Add(new Job() { job_id = (string)result[i]["job_id"], job_number = (string)result[i]["job_number"], ship_type = (string)result[i]["ship_type"] }); } lstJobData.ItemsSource = Jobs; } } internal class Job { public string job_id { get; set; } public string job_number { get; set; } public string ship_type { get; set; } } 时该值可用是不安全的。

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(...)(或任何其他生命周期回调)被调用并完成后,这可能会很长。

答案 1 :(得分:0)

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

  • 尝试使用像private optionsSource = new BehaviorSubject<Options>(null);这样的BehaviorSubject。

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

app.component.ts

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

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

sidebar.component.ts

  • 尝试将订阅从constructor移至ngOnInit

以下是plnk以上修改供您参考。