使用RxJS的Angular 5+同级组件通信(主题) [英] Angular 5+ Sibling Component Communication Using RxJS (Subject)

查看:63
本文介绍了使用RxJS的Angular 5+同级组件通信(主题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序具有单击时将显示在仪表板中的图块列表.在仪表板中,单击磁贴时,磁贴详细信息显示在仪表盘下方(与英雄之旅不同).

My app has listing of tiles that when clicked on will display in a dashboard. In the dashboard, when a tile is clicked, the tile details show below the dashboard (not unlike tour-of-heroes).

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

I’m using RxJS Subject in a service to communicate successfully between Component A (available snippets), Component B (the dashboard), and the Component C (snippet details).

问题是,当我单击组件A上的一个清单时,它不仅像应有的那样填充了仪表板,而且还填充了详细信息(组件C).我只希望在仪表板中单击图块时填充详细信息-是的,单击仪表板图块时,确实可以成功填充详细信息.

The problem is that when I click on the one of the listings on component A, not only does it populate the dashboard like it should but also populates the details (Component C). I only want the details to be populated when the tile is clicked on in the dashboard - yes, the details do successfully populate when a dashboard tile is clicked.

所有3个组件都是位于app.component.html中的兄弟姐妹.我不希望有亲子关系-因此使用 Subject 而不是 @Inupt .

All 3 components are siblings residing in app.component.html. I do not want parent-child relationships - hence using Subject instead of @Inupt.

服务:

@Injectable()
export class SnippetService {

  tile  = new Subject<any>();

  constructor() { }

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

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

}

组件A(可用的图块/片段):

Component A (available tiles/snippets):

@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 C (snippet details)

@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 {} 与C视图中的 * ngIf ="snippet "之间.我尝试从服务中传递其他布尔值,但问题是我需要这些布尔值的状态处于生命周期循环中.

So the the culprit is between the ngOnInit{} in Component C and the *ngIf="snippet" on C's view. I tried passing additional booleans from the service but the problem is that I need the state of those bools to be in a lifecycle loop.

那么RxJS可以做到这一点吗?

So a RxJS'y way of doing this?

推荐答案

服务:

@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(仪表板)现在将代码段传递到代码段.service showDetails()方法:

Component B (Dashboard) now passes the snippet to the snippet.service showDetails() method:

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

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

Component C (details) now subscribes to the details subject and assigns the result to C's snippet property:

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

这篇关于使用RxJS的Angular 5+同级组件通信(主题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆