извлеките объявление из службы, чтобы отобразить его в компоненте

#angular #typescript

Вопрос:

Я хочу, чтобы мой счетчик лайков обрабатывался в моем компоненте post.service, поэтому я объявил postLoveIts в поле компонента моего класса post.service, но я не знаю, как получить его в моем компоненте post-list.и отобразить его в моем шаблоне post-list.component… спасибо за вашу помощь !

post.service.ts:

 import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Post } from '../models/post.model';

@Injectable()
export class PostsService {
  
  postLoveIts : number = 0 ;

  private posts : Post[] = [
    {
          title: "Cuite mémorable avec mes friends",  
          content: "lorem ipsum",  
    }
  ];
  postsSubject = new Subject<any[]>();

  emitPosts() {
      this.postsSubject.next(this.posts);
    }

  
  createNewPost(newPost : Post) {
    this.posts.push(newPost);
    this.emitPosts();
  }

  removePost(post : Post) {
    const postIndexToRemove = this.posts.findIndex(
      (postEl) => {
        if(postEl === post) {
          return true;
        } else {
          return ' '
        }
      }
    );
    this.posts.splice(postIndexToRemove, 1);
    this.emitPosts();
  }



  addOne() {
    this.postLoveIts = this.postLoveIts   1;
    console.log("like(s) :"   this.postLoveIts);
  }


  subtractOne() {
    this.postLoveIts = this.postLoveIts -1;
    console.log("like(s) :"   this.postLoveIts);
  }

 

post-list.component.ts :

 import { Component, OnInit, Input, Output, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { Post } from '../models/post.model';
import { PostsService } from '../services/posts.service';


@Component({
  selector: 'app-post-list',
  templateUrl: './post-list.component.html',
  styleUrls: ['./post-list.component.scss']
})
export class PostListComponent implements OnInit, OnDestroy {
  

  posts : Post[];
  postsSubscription: Subscription;
  postLoveIts : number = 0 ;

  constructor(private postsService: PostsService,
              private router: Router) { }

  ngOnInit(): void {
    this.postsSubscription = this.postsService.postsSubject.subscribe(
      (posts: Post[]) => {
        this.posts = posts;
      }
    );
    this.postsService.emitPosts()
  }

  onAddOne() {
    this.postsService.addOne();
  }


  onSubtractOne() {
    this.postsService.subtractOne()
  }

  onDeletePost(post: Post) {
    this.postsService.removePost(post);
  }

  ngOnDestroy() {
    this.postsSubscription.unsubscribe();
  }
}

 

и post-list.component.html:

 
      <ul class="list-group">
            <li class="list-group-item" *ngFor="let post of posts">
                  <h3> {{ post.title }} </h3>
                  <p>  {{ post.content }} </p>
                  <p> {{ postLoveIts }} </p>   

                  <div class="container">
                        <button class="btn btn-success pull-left" (click)="onAddOne()"> J'aime </button>
                        <button class="btn btn-danger pull-left" (click)="onSubtractOne()"> J'aime pas </button>
                  
                  
                        <div class="col-md-10">
                              <button type="button" class="btn btn-primary pull-right" 
                              (click)="onDeletePost(post)"> Supprimer </button>
                        </div>
                  </div>
            </li>
      </ul>


 

Ответ №1:

Создайте тему для внесения изменений postLoveIts в свой сервис, а затем подпишитесь на эту тему в своем компоненте, в подписке вы можете просто обновить значение своего postLoveIts поля в компоненте.

Что-то вроде этого (я пропустил ваш код для удобства чтения, но предполагаю, что он там есть):

 export class PostsService {
  
  private postLoveIts$: Subject<number> = new Subject<number>();

  private emitUpdatedPostLoveIts(): void {
    this.postLoveIts$.next(this.postLoveIts);
  }

  watchPostLoveIts(): Observable<number> {
    return this.postLoveIts$.asObservable();
  }

  // below methods already exist in your code but I added one line to each of them
  addOne() {
    this.postLoveIts = this.postLoveIts   1;
    console.log("like(s) :"   this.postLoveIts);
    emitUpdatedPostLoveIts(); // <- this is new line in this method
  }


  subtractOne() {
    this.postLoveIts = this.postLoveIts -1;
    console.log("like(s) :"   this.postLoveIts);
    emitUpdatedPostLoveIts(); // <- this is new line in this method
  }
}
 

а затем просто понаблюдайте за этими изменениями постловейтов в компоненте:

 export class PostListComponent implements OnInit, OnDestroy {
  
  ngOnInit(): void {
    this.postsSubscription = this.postsService.postsSubject.subscribe(
      (posts: Post[]) => {
        this.posts = posts;
      }
    );
    this.postsService.emitPosts()

    this.postsService.watchPostLoveIts().subscribe(postLoveIts => {
      this.postLoveIts = postLoveIts;
    });
  }
}
 

Комментарии:

1. спасибо тебе, Павел ! У вас есть какие-либо идеи о том, как я могу привязать этот метод к каждому сообщению отдельно, потому что теперь он работает нормально, но он находится в компоненте списка сообщений. Нужно ли для этого создавать компонент с одним сообщением ? спасибо вам за помощь

2. @GooshFen, вы можете добавить атрибут postLoveIts в модель публикации, чтобы хранить его для каждой публикации отдельно. Тогда вам просто нужно внести некоторые изменения: удалить атрибут postLoveIts из сервиса и принять объект post в методах addOne / subtractOne в сервисе. postLoveIts$ в сервисе можно было бы заменить, updatedPosts$: Subject<Post> и вы могли бы отправлять обновленные сообщения из него. Таким образом, addOne/subtractOne изменит параметры postLoveIts сообщения из параметра, а затем выдаст это сообщение как обновленное. В компоненте вам нужно будет найти это сообщение в списке this.posts и обновить его.

3. хорошо, спасибо, я могу попробовать, но дело в том, что post.model больше подходит для пользователя, когда он хочет создать новый пост, поэтому у него будет выбор добавить номер лайка, ха-ха… Я посмотрю, что я могу сделать

4. @GooshFen, вам не нужно предоставлять пользователю возможность изменять его. Здесь у вас есть несколько вариантов, в зависимости от того, как вы инициализируете публикацию (как выглядят ваши формы), но, как правило, вы можете просто инициализировать эту модель, установив значение postLoveIts равным нулю по умолчанию (вы можете назначить нулевое значение по умолчанию в модели) и не размещайте никаких входных данных или каких-либо других компонентов, которые могли бы изменить его, когда пользователь создает публикацию. Таким образом, сообщение может состоять из текста и сообщений, и пользователь будет видеть ввод только для текста и изменять только этот.