使用RxJS进行Angular 5+同级组件通信(主题)

时间:2018-04-18 00:32:34

标签: angular rxjs

我的应用程序列出了点击时会显示在信息中心内的图块。在仪表板中,单击图块时,图块详细信息显示在仪表板下方(与英雄游览不同)。

我在服务中使用RxJS Subject在组件A(可用代码段),组件B(仪表板)和组件C(代码段详细信息)之间成功通信。

问题在于,当我点击组件A上的其中一个列表时,它不仅会像应该那样填充仪表板,还会填充详细信息(组件C)。我只希望在仪表板中单击磁贴时填充详细信息 - 是的,单击仪表板磁贴时,详细信息会成功填充。

所有3个组件都是驻留在app.component.html中的兄弟。 我不想要父子关系 - 因此使用Subject代替@Inupt

服务:

@Injectable()
export class SnippetService {

  tile  = new Subject<any>();

  constructor() { }

  getSnippets(): Observable<Snippet[]> {
    return of (SNIPPETS);
  }

  addTile(data) {
    this.tile.next(data);
  }

}

组件A(可用的磁贴/片段):

@Component({
  selector: 'app-available-snippets',
  templateUrl: './available-snippets.component.html',
  styleUrls: ['./available-snippets.component.css']
})
export class AvailableSnippetsComponent implements OnInit {

  snippets: Snippet[];

  constructor(private snippetService: SnippetService) { }

  ngOnInit() {
    this.getSnippets();
  }

  getSnippets(): void {
    this.snippetService.getSnippets().subscribe(x => this.snippets = x);
  }

  onAddTile(data) {
    this.snippetService.addTile(data);
  }

}

组件B(仪表板):

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

  selectedSnippet: Snippet;

  addedSnippets = [];

  // Inject the SnippetService
  constructor(private snippetService: SnippetService) { }

  ngOnInit() {
    this.snippetService.tile.subscribe(x => this.addToDashboard(x));
  }

  addToDashboard(s: Snippet) {
    if (this.addedSnippets.indexOf(s) === -1) {
      this.addedSnippets.push(s);
    }
  }

  displayDetails(s: Snippet) {
    this.snippetService.addTile(s);
  }

}

组件C(摘录详细信息)

@Component({
  selector: 'app-snippet-detail',
  templateUrl: './snippet-detail.component.html',
  styleUrls: ['./snippet-detail.component.css']
})
export class SnippetDetailComponent implements OnInit {

  snippet: Snippet;

  constructor(private snippetService: SnippetService) { }

  ngOnInit() {
   this.snippetService.tile.subscribe(x => this.snippet = x);
  }

}

组件C模板:

<div class="snippet-detail" *ngIf="snippet">
  <hr>
  <h2>{{ snippet.title }} </h2>
  <div>{{snippet.description}}</div>
  <code>{{snippet.code.example1}}</code>
  <code>{{snippet.code.example2}}</code>
  <code>{{snippet.code.example3}}</code>
</div>

因此,罪魁祸首是在组件C中的ngOnInit{}*ngIf="snippet&#34;之间。在C的观点。我尝试从服务中传递额外的布尔值,但问题是我需要那些bool的状态处于生命周期循环中。

这是RxJS的做法吗?

2 个答案:

答案 0 :(得分:0)

服务:

@Injectable()
export class SnippetService {

  tile  = new Subject<any>();
  details  = new Subject<any>();

  constructor() { }

  getSnippets(): Observable<Snippet[]> {
    return of (SNIPPETS);
  }

  addTile(data) {
    this.tile.next(data);
  }

  showDetails(data) {
    this.details.next(data);
  }

}

组件B(仪表板)现在将代码段传递给snippet.service showDetails()方法:

  displayDetails(s: Snippet) {
    this.snippetService.showDetails(s);
  }

组件C(详细信息)现在订阅详细信息主题并将结果分配给C的代码段属性:

 ngOnInit() {
   this.snippetService.details.subscribe(x => this.snippet = x);
  }

答案 1 :(得分:0)

我发现在某些情况下,发送 Observable <primitive> ie: Observable<boolean>() 您需要将布尔值包装在这样的对象中。

//In a component somewhere.

// decleration of observable 
scrollTopNotify$: Observable<BooleanValue> = of<BooleanValue>({value: false});

//  setting a value later.  Because it is now an object the reference changes and
//  it triggers the change more reliably for subscribers and async pipe subscribers.
this.scrollTopNotify$ = of<BooleanValue>({value: true});

// ie: in template: [scrollTopNotify]="(scrollTopNotify$ | async)">

//boolean-value.ts file
export interface BooleanValue {
    value: boolean;
}