设置可观察,并在发生更改时进行更新

时间:2018-10-03 20:18:44

标签: angular rxjs observable

嗯,正在消耗API服务:

getServers():Observable<Server[]>{
    return this.httpClient.get(this.API_URL).pipe(map((servidores:Server[]) =>{
        const servidores2 = plainToClass(Server, servidores as object[]) ;
        servidores2.forEach(servidor => {
            this.getApps2(servidor.ServerId, apps =>{
              servidor.Applications = new Array(apps.length);
              servidor.Applications = apps ;
            });
        });
        return servidores2;
      }));
  }

因此我从“ ServerListComponent”调用它:

@Injectable()
export class ServerListComponent implements OnInit {
  @Input() servers$: Observable<Server[]>;
  public serverCards:Server;
  constructor(private serverAPI: ServersService){}

  ngOnInit(){ this.servers$ = interval(5000).pipe(startWith(0)).pipe( switchMap(() => this.serverAPI.getServers())); }

  ngOnDestroy() { }

}

当然,在HTML中,我会发送到另一个子组件:

  <server-card *ngFor="let server of servers$ | async" [serverCards] = "server" ></server-card>  

现在我的问题是,即使数据相同,它也会每5秒闪烁一次并重新执行视图。因此,我想做的就是仅在发生更改时刷新视图。

export class ServerCardComponent{ 
  private _serverCards: Observable<Server>;
  asyncTabs: Observable<Tabs>; 


  @Input() 
  set serverCards(servidor:Observable<Server>) {
    if(servidor == this._serverCards){
      //if data is the same do nothing
    }else{
      //only update if data changed
      this._serverCards  = servidor;
    }


  }

  get serverCards():Observable<Server> {

    return this._serverCards;
  }

当然,最后的努力工作了,我不知道如何“比较”两个可观察对象,并且仅在数据不同的情况下才更新模板。或zip,但我不知道如何为我的解决方案实施。

如果需要,我的cardServer模板如下:

<mat-card class="dashboard-card"> 

    <mat-card-header class="header-cardsita">

        <div mat-card-avatar class="led-box"><div class="{{serverCards.State | stateLed}}"></div></div>
        <mat-card-title>
            <div mat-card-avatar class="redondo-avatar-pc"></div>

          <p ><a class="title-cardsita" href="/Admin/server/{{serverCards.ServerId}}">{{serverCards.Hostname}}</a> </p>
        </mat-card-title>
        <mat-card-subtitle><p class="subtitulo">{{serverCards.Ip }}</p></mat-card-subtitle>

        <button mat-icon-button class="more-button" [matMenuTriggerFor]="menu" aria-label="Toggle menu">
          <mat-icon>more_vert</mat-icon>
        </button>
              <mat-menu #menu="matMenu" xPosition="before">
                <a class="enlace" href="/Admin/server/{{serverCards.ServerId}}">
                    <button mat-menu-item>Details</button>
                </a>

                <button mat-menu-item>Edit</button>
                <button mat-menu-item>Delete</button>
              </mat-menu>


    </mat-card-header>
    <mat-divider class="divisor-top"></mat-divider>


    <mat-card-content class="dashboard-card-content">
        <p class="content-icons"><i class="material-icons color-accent">group</i>{{serverCards.Team}}</p>

        <p class="content-icons"><i class="material-icons color-accent">subdirectory_arrow_right</i>{{serverCards.OperatingSystem}}</p>



        <p class="content-icons"><i class="material-icons color-accent">label</i></p><p class="description">{{serverCards.Description | truncate : 90 : "..."}}</p>

        <mat-divider ></mat-divider>

              <br>
              <ul *ngIf="serverCards.Applications" >
                  <li *ngFor="let app of serverCards.Applications">{{app.Name}}</li>
              </ul>







    </mat-card-content>
  </mat-card>

谢谢。

1 个答案:

答案 0 :(得分:0)

好吧,这是我最后的想法,希望它能对遇到同样问题的人有所帮助:

首先,我创建一个可观察到的对象,每5秒消耗一次我的API

servidores$ =  interval(5000).pipe(startWith(0)).pipe( switchMap(() => this.getServersOnly()));

下一步是什么?当然,我只想接收不同的东西。

getServersDistinct():Observable<Server[]>{
   return this.servidores$.pipe(distinctUntilChanged((p:Server[], q:Server[]) => (JSON.stringify(p) === JSON.stringify(q))));
  }

利润,现在我的模板中带有管道|现在,异步仅在数据已更改时更新。我不知道代码是否可以变得更好,但是对我有用。