【问题标题】:Angular 5+ Sibling Component Communication Using RxJS (Subject)Angular 5+ 使用 RxJS 的兄弟组件通信(主题)
【发布时间】:2018-04-18 00:32:33
【问题描述】:

我的应用程序有一个磁贴列表,点击后会显示在仪表板中。在仪表板中,单击图块时,图块详细信息会显示在仪表板下方(与英雄之旅不同)。

我在服务中使用 RxJS 主题在组件 A(可用的 sn-ps)、组件 B(仪表板)和组件 C(sn-p 详细信息)之间成功通信。

问题在于,当我单击组件 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(可用的切片/sn-ps):

@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(sn-p 详细信息)

@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" 之间。我尝试从服务中传递额外的布尔值,但问题是我需要这些布尔值的状态处于生命周期循环。

那么是 RxJS 的做法吗?

【问题讨论】:

  • 你需要在你的服务中有多个主题。一个用于显示在仪表板上的磁贴,另一个用于显示在详细视图中的磁贴。
  • 此外,您不能在拥有父子关系的情况下仍然使用@Input()s。使用@Output()s 将数据广播到您的父组件,该组件通过@Input() 提供数据。
  • @DanielWSrimpel 谢谢。根据您的评论发布答案。

标签: angular rxjs


【解决方案1】:

服务:

@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(仪表板)现在将 sn-p 传递给 sn-p.service showDetails() 方法:

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

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

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

【讨论】:

    【解决方案2】:

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

    //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;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      • 2017-01-01
      • 2016-07-08
      • 2017-05-04
      相关资源
      最近更新 更多