简体   繁体   English

Angular和RxJS:更新主题?

[英]Angular and RxJS: Updating the Subject?

This is along the lines of my question here but now I have a new issue. 这符合我在这里提出的问题但是现在我有一个新问题。

My app shows a dashboard of tiles. 我的应用程序显示了一个磁贴的仪表板。 I'm using Subjects for component communication. 我正在使用主题进行组件通信。 When a tile is removed from the dashboard, I need the the data from the tile-details.component 's view to disappear. 从仪表板上删除磁贴时,我需要从tile-details.component的视图中删除数据。 As it is, the data remains in the details view after the tile is removed. 照原样,删除磁贴后,数据仍保留在详细信息视图中。

I wanted to accomplish this by manipulating the data stream (the details subject), since that is what tile-details.component is reacting to. 我想通过操纵数据流(详细信息主题)来完成此操作,因为这是tile-details.component的反应。

Here's the service: 这是服务:

@Injectable()
export class TileService {

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

  tiles = [];

  constructor() { }

  getTiles(): Observable<Tile[]> {
    return of (TILES);
  }

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

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

dashboard.component.ts: dashboard.component.ts:

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

  title = 'Dashboard';

  // Tiles to show on dashboard
  tiles = [];

  editing = false;

  constructor(private tileService: TileService) { }

  ngOnInit() {
    // We only want tiles that have been clicked on in available-tiles.component to show in the dashboarrd.
    // The available-tiles.component adds to the tiles subject when a tile is clicked.
    // Populate the tiles array based on the data stream from the tile subject.
    this.tileService.tile.subscribe(x => this.populateTilesArr(x));
  }

  populateTilesArr(t: Tile) {
    if (this.tiles.indexOf(t) === -1) {
      this.tiles.push(t);
    }
  }

  remove(t) {
     // remove tile from array
    const index = this.tiles.indexOf(t);
    this.tiles.splice(index, 1);

   // *** Do something with details subject here? ***

    if (this.tiles.length < 1) {
      this.editing = false;
    }

  }

  displayDetails(t: Tile) {
    this.tileService.addDetail(t);
  }

}

dashboard.component.html: dashboard.component.html:

<div class="wrapper">
  <h3>{{ title }}</h3>
  <p *ngIf="tiles.length >= 1; else instructions">Click a tile to view code snippets</p>
  <ng-template #instructions>
      Click a tile from the selection on the left to populate the dashboard.
  </ng-template>
<div *ngIf="tiles.length >= 1">
    <button (click)="editing = true" [disabled] = "editing">Edit Dashboard</button>
    <button *ngIf="editing" (click)="editing = false">Done</button>
</div> 
  <ul>
      <li *ngFor = "let tile of tiles" (click)="displayDetails(tile)">
        <button  *ngIf="editing" class="remove" (click)="remove(tile)">X</button>
        <span class="title">{{tile.title}}</span> 
        <span class="desc">{{tile.description}}</span>
    </li>
  </ul>
</div>

tile-detail.component.ts: 瓦detail.component.ts:

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

  tile: Tile;

  constructor(private tileService: TileService) { }

  ngOnInit() {
    this.tileService.details.subscribe(x => this.tile = x);
  }

}

tile-detail.component.html: 瓦detail.component.html:

<div class="wrapper" *ngIf="tile">
  <hr>
  <h2>{{ tile.title }} </h2>
  <p>{{tile.description}}</p>
    <code>{{tile.code.snippetA}}</code>
    <code>{{tile.code.snippetB}}</code>
    <code>{{tile.code.snippetC}}</code>
</div>

Based on what you have in your tile detail component, you should just need to null out your tile property. 根据您的图块详细信息组件中的内容,您只需要null tile属性即可。 Tracing back through the tile service and dashboard, you can just push a new null value in your service from your dashboard like this in your remove method: 追溯到tile服务和仪表板,您可以像这样在remove方法中从仪表板中推送服务中的新null值:

this.tileService.addDetail(null);

Update 更新

Based on your comment below, you'll need to update your dashboard component to hold onto the selected tile shown in the detail view. 根据下面的评论,您需要更新仪表板组件,以保留在详细视图中显示的所选图块上。

selectedTile: Tile;

Now when you select a tile you need to not only use your service, you need to set this new property to it: 现在,当您选择一个图块时,您不仅需要使用服务,还需要为其设置以下新属性:

displayDetails(t: Tile) {
    this.tileService.addDetail(t);
    this.selectedTile = t;
}

Additionally, you need to modify the remove code to this (in place of the original code above): 此外,您需要为此修改删除代码(代替上面的原始代码):

if (this.selectedTile === tile) {
    this.displayDetails(null);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM