首页 > 解决方案 > 两个组件之间的交互

问题描述

我需要一些帮助。我有一个主页和一个收藏页面(另一个组件) 在主页中,用户输入了一个电影列表,在这个列表中它显示了 2 个按钮(删除和收藏)我的问题是当我按下收藏按钮时我想要的收藏它会将其添加到收藏夹列表中,当我转到收藏夹页面时,它将显示收藏夹列表。

你能帮我吗?我是网络编程的新手。

我的 home.component.ts:

import { Component } from '@angular/core';
@Component({ 
    selector: 'app-home', 
    templateUrl: './home.component.html', 
    styleUrls: ['./home.component.css'] 
}) 
export class HomeComponent { 
    /* Un tableau vide dans lequel vont être ajoutés les entrées.*/
    public films = [];
    public favorites = [];
  
    /* Ajout des élèments en entrée dans la liste avec vérification que le texte n'est pas vide.*/
    public newFilm; 
    public addToList() { 
        if (this.newFilm == '') { 
        } 
        else { 
            this.films.push(this.newFilm); 
            this.newFilm = ''; 
        } 
    } 
    /*Fonction permettant l'ajout d'un element à la liste des favoris*/
    public addtofav(index){
        this.favorites.push(this.newFilm);
    }
  
    /*Fonction permettant la suppression d'une élement de la liste des films et de favoris*/
    public deleteTask(index) { 
        this.films.splice(index, 1); 
        this.favorites.splice(index, 1);
    }
}

我的 home.component.html:

  <div class="row bg-dark justify-content-center 
          align-items-center" style="height:100px"> 
      <div class="col-5"></div> 
      <div class="col-6 text-white h2"> 
         Home Page
      </div> 
  </div>
  
  <!--Bloc s'occupant des inputs -->
  <div class="row mt-1" style="height:80px;"> 
    <div class="col-3 d-none col-md-3 d-md-block"></div> 
      <div class="col-12 col-md-6 bg-dark d-flex  
      justify-content-center align-items-center  
      text-light h3"> 
          <input [(ngModel)]="newFilm" type="text" 
                  value="" class="col-7 form-control"
                      style="width:300px;"> 

          <div class="col-1"></div> 

          <button (click)="addToList()"  
          class="btn btn-light text-danger"> 
              Ajoutez un film
          </button> 
      </div> 

      <div class="col-3 d-none col-md-3 d-md-block"></div> 
  </div> 

  <!--Bloc s'occupant de la liste des films-->
  <div *ngFor="let x of films; let index = index;" 
          class="row mt-1" style="height:100px;">

      <div class="col-3 d-none col-md-3 d-md-block"></div> 

      <div class="col-12 col-md-6 bg-dark d-flex 
                  justify-content-center align-items-center 
                  text-light h3"> 

          <div class="col-8 text-light h3">{{x}}</div> 

          <input (click)="deleteTask(index)" type="button"
              value="Delete" class="col-2 btn btn-danger"> 
          <input (click)="addtofav(index)" type = "button"
              value="Fav" class = "col-2 btn btn-success">
      </div>
        
      <div class="col-3 d-none col-md-3 d-md-block"></div> 
  </div> 
</div> 
`


标签: angular

解决方案


我正在扩展 Mike S. 的答案。

如果组件处于父子关系中,您可以在组件之间共享数据。您还可以使用服务在它们之间共享数据。

在您的情况下,最好有一个带有可观察数组的服务,您的收藏夹组件可以订阅该服务以获得收藏夹列表。

服务:

@Injectable()
export class SharedService {

  constructor() { }

  //you need to have an existing array in order to assing it to an observable one
  //since you cant directly push to ovbservable arrays
  private favouritesSource: string[] = [];
  favourites: Subject<string[]> = new Subject();

  addToFavourites(film: string){
    this.favouritesSource.push(film);
    this.favourites.next(this.favouritesSource);
  }
}

收藏夹组件:

export class FavouritesComponent implements OnInit {

  constructor(private sharedService: SharedService) { }

  favourites: string[];

  ngOnInit() {
    //assigning the array from the service to the one that displays the favourites
    this.sharedService.favourites.subscribe(favourites => {
      this.favourites = favourites;
    })
  }
}

电影组件:

export class MoviesComponent {

  constructor(private sharedService: SharedService) { }

  addToFavourites(film: string){
    this.sharedService.addToFavourites(film);
  }
}

我希望这有帮助 :)

编辑

此方法仅在两个组件同时显示时才有效,这意味着使用此方法的路由将不起作用。

这是因为当您使用 angulars 路由器导航并使用 显示组件router-outlet时,正在显示的组件会重新加载。这意味着该ngOnInit()方法会再次被调用,随后还会调用.subscribe()可观察对象的方法。

这样做的问题是,.subscribe()只有在可观察值发生更改时才会触发内部的语句,并且由于未加载可以启动可观察值更改的组件,因此.subscribe()不会触发内部的语句。

编辑 2

如果您必须使用 angulars 路由器在 2 个组件之间导航,这是示例。

服务:

@Injectable()
export class SharedService {

  constructor() { }

  private favourites: string[] = [];

  addToFavourites(film: string){
    this.favourites.push(film);
  }

  getFavourites(){
    return this.favourites;
  }
}

电影组件:

xport class MoviesComponent {

  constructor(private sharedService: SharedService) { }

  addToFavourites(film: string){
    this.sharedService.addToFavourites(film);
  }
}

收藏夹组件:


  constructor(private sharedService: SharedService) { }

  favourites: string[];

  ngOnInit() {
    this.favourites = this.sharedService.getFavourites();
  }

}

导航可以像这样发生:

constructor (private router: Router){}

this.router.navigate(['urlToNavigateTo']);

或这个:

<anyHtmlElement routerLink="/urlToNavigateTo">Navigate to url</anyHtmlElement>

Stackblitz 示例


推荐阅读