Angular 5 - Как игнорировать обновление одного свойства 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.info('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.info('Done'));
}

Я не уверен, что точно понимаю, в чем проблема. Вы хотите пропустить создание нового запроса после того, как вам понравилось видео? Почему бы вам не обновить модель напрямую?

Andrei Tătar 30.05.2018 13:59

Пожалуйста, добавьте функции setLike и revokeLike

Sravan 30.05.2018 14:00

@Sravan добавлены две функции!

Mahmood Kohansal 30.05.2018 14:03

@Andrew Я хочу обновить модель после того, как мне понравилось видео, так как теперь она работает правильно. но проблема заключается в обновлении модели, обновлении значений в html и обновлении окон iframe для видео мне не подходит.

Mahmood Kohansal 30.05.2018 14:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
4
297
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Судя по информации, я бы сделал так. Идея состоит в том, что нет необходимости запрашивать у серверной части список видео, поскольку вы знаете, что и как изменилось, и вы применяете изменение только в том случае, если у вас есть положительный ответ.

Шаблон:

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

}

Вы можете сделать это в функциях setLike и revokeLike, отправить video object в function и makeisLiked, чтобы изменить 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;
        }
    );
}

Ваш ответ правильный, большое спасибо, но Эндрю ответил за мгновение до вас.

Mahmood Kohansal 30.05.2018 14:22

Все в порядке, @MahmoodKohansal, кто бы ни ответил первым, наша цель - помогать людям. :-)

Sravan 30.05.2018 14:23

Другие вопросы по теме