Angular 5 - 如何忽略更新一个 属性 Observable

Angular 5 - How to ignore updating one property of Observable

我正在开发一个页面来显示一些视频,用户可以喜欢它们。视频和点赞保存在数据库中,我使用了两个 angular 服务来设置和获取数据。我的问题是关于设置和撤销对视频的点赞。在每次像视频一样请求设置或撤销之后,页面数据都会被刷新,加载视频会让用户感到不安。服务工作正常,数据集正确地连接到数据库。

我只需要在页面中更新点赞按钮颜色和点赞数。 忽略更新固定且从未更改的视频链接 的解决方案是什么?

下面是我的部分代码:

index.component.html :

<mat-card class="example-card" *ngFor="let video of videos">
    <mat-card-header>
        <mat-card-title>{{ video.title }}</mat-card-title>
        <mat-card-subtitle>
            {{ video.description }}
        </mat-card-subtitle>
    </mat-card-header>
    <div class="video-container">
        <iframe class="video-frame" [src]="video.mediaSource | safe" allowFullScreen="true" webkitallowfullscreen="true" mozallowfullscreen="true" ></iframe>
    </div>
    <mat-card-actions class="text-center">
        <button *ngIf="video.isLiked == true" mat-icon-button color="warn">
            <mat-icon (click)="revokeLike(1, video.id)">favorite</mat-icon>
        </button>

        <button *ngIf="video.isLiked == false" mat-icon-button class="grey_like">
            <mat-icon (click)="setLike(1, video.id)">favorite</mat-icon>
        </button>
        <span>{{ competition.likesCount }} Likes</span>
    </mat-card-actions>
</mat-card>

index.component.ts :

export class ShowComponent implements OnInit {

    competitions:any;

    constructor(private service:VideoService, private http: HttpClient, private likeservice:LikeService) { }

    ngOnInit() {
        this.getVideos();
    }

    getVideos() {
        this.service.getVideos(1).subscribe(res => {
            this.videos = res;
        });
    }

    setLike(iid, video_id) {
        this.likeservice.setLike(iid, video_id).subscribe(
            () => this.getCompetitions()
        );
    }

    revokeLike(iid, video_id) {
        this.likeservice.revokeLike(iid, video_id).subscribe(
            () => this.getCompetitions()
        );
    }

}

videos.service.ts :

getVideos(id): Observable<any> {
    const uri = 'http://localhost:4000/videos/iid/' + id;
    return this
        .http
        .get(uri)
        .map(res => {
            return res;
        });
}

like.service.ts :

setLike(iid, competition_id) {
    const uri = 'http://localhost:4000/likes/set';
    const obj = {
        iid: iid,
        competition_id: competition_id
    };

    return this
        .http
        .post(uri, obj)
        .map(res =>
            console.log('Done'));
}

revokeLike(iid, competition_id) {
    const uri = 'http://localhost:4000/likes/revoke';
    const obj = {
        iid: iid,
        competition_id: competition_id
    };

    return this
        .http
        .post(uri, obj)
        .map(res =>
            console.log('Done'));
}

根据资料,我会这样做。这个想法是不需要重新查询视频列表的后端,因为您知道 what/how 已更改,并且只有在响应正常时才应用更改。

模板:

<mat-card class="example-card" *ngFor="let video of videos">
    ...
    <button *ngIf="video.isLiked == true" mat-icon-button color="warn">
        <mat-icon (click)="revokeLike(video)">favorite</mat-icon>
    </button>

    <button *ngIf="video.isLiked == false" mat-icon-button class="grey_like">
        <mat-icon (click)="setLike(video)">favorite</mat-icon>
    </button>
    ...
</mat-card>

控制器:

export class ShowComponent implements OnInit {

    competitions:any;

    constructor(private service:VideoService, private http: HttpClient, private likeservice:LikeService) { }

    ngOnInit() {
        this.getVideos();
    }

    getVideos() {
        this.service.getVideos(1).subscribe(res => {
            this.videos = res;
        });
    }

    setLike(video) {
        this.likeservice.setLike(1, video.id).subscribe(
            () => video.isLiked = true
        );
    }

    revokeLike(video) {
        this.likeservice.revokeLike(1, video.id).subscribe(
            () => video.isLiked = false
        );
    }

}

您可以在 setLikerevokeLike 函数中执行此操作,将 video object 发送到 functionmake isLiked 以更改 accordingly

这使得 *ngIf 条件对您有效。

HTML:

<mat-card-actions class="text-center">
    <button *ngIf="video.isLiked == true" mat-icon-button color="warn">
        <mat-icon (click)="revokeLike(1, video)">favorite</mat-icon>
    </button>

    <button *ngIf="video.isLiked == false" mat-icon-button class="grey_like">
        <mat-icon (click)="setLike(1, video)">favorite</mat-icon>
    </button>
    <span>{{ competition.likesCount }} Likes</span>
</mat-card-actions>

分量:

setLike(iid, video) {
    this.likeservice.setLike(iid, video.id).subscribe(
        data => {
            video.isLiked = true;
        }
    );
}

revokeLike(iid, video) {
    this.likeservice.revokeLike(iid, video.id).subscribe(
        data => {
            video.isLiked = false;
        }
    );
}