我正在创建一个电影数据库,我希望它能使用户在“搜索电影”组件(显示电影列表)上时,单击“添加到收藏夹”按钮电影,然后将该电影添加到另一个名为“收藏夹”的组件中?
我尝试使用@Output()EventEmitter,但似乎无法正常工作。我认为,如果从Service.ts文件中处理它也会更好,但是我仍然很难实现这一点,非常感谢您的帮助!
在favourites.component.ts文件中,我添加了一个空的myFavs = [];阵列,准备将喜爱的电影推入其中。
/* search-movie.component.ts */
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { DataService } from '../data.service';
@Component({
selector: 'app-search-movie',
templateUrl: './search-movie.component.html',
styleUrls: ['./search-movie.component.css']
})
export class SearchMovieComponent implements OnInit {
searchControl = new FormControl('');
movieResults: any = [];
constructor(
private data: DataService) { }
ngOnInit() {
}
/* GET request*/
getData(event) {
const film = event.target.value;
this.data.searchFilm(film)
.subscribe( (res) => {
res = this.movieResults = res;
console.log(res);
});
}
}
/* search-movie.component.html */
<div class="container">
<h1 class="is-size-1">Find your favorite movies:</h1>
<form (ngSubmit)="onSubmit()">
<input
type="text"
(keyup)="getData($event)"
placeholder="Start typing..."
[formControl]="searchControl" />
</form>
</div>
<div class="container">
<ul>
<li id="list-item" *ngFor="let x of movieResults; let i = index;">
<img
[src]="x.Poster"
onerror="this.src='../assets/images/default-poster.jpg'"
[routerLink]="['/movie/' + x.imdbID]">
<p
id="movie-title"
class="is-size-5">{{x.Title}} ({{x.Year}}) </p>
<button (click)="" >ADD TO FAVS</button>
</li>
</ul>
</div>
/* favourites.component.ts */
import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
@Component({
selector: 'app-favourites',
templateUrl: './favourites.component.html',
styleUrls: ['./favourites.component.css']
})
export class FavouritesComponent implements OnInit {
myFavs = [];
constructor(
private data: DataService
) { }
ngOnInit() {
}
}
/* favourites.component.html */
<h1>FAVS</h1>
<div class="container">
<ul>
<li id="list-item" *ngFor="let x of myFavs; let i = index;">
<img
[src]="x.Poster"
onerror="this.src='../assets/images/default-poster.jpg'"
[routerLink]="['/movie/' + x.imdbID]">
<p
id="movie-title"
class="is-size-5">{{x.Title}} ({{x.Year}}) </p>
</li>
</ul>
</div>
答案 0 :(得分:1)
在数据服务中,创建如下的行为主题
// observable
public favouritesList = new BehaviorSubject<any>({});
public favouritesList$ = this.favouritesList.asObservable();
并在服务层中编写一个方法
tiggerFavouritesList(data) {
this.favouritesList.next(data);
}
在组件一中,当您单击
<button (click)="addFavourites(x)" >ADD TO FAVS</button> // call a method like
addFavourites(data) {
this.dataService.tiggerFavouritesList(data);
}
在第二部分中,订阅主题
this.dataService.favouritesList$.pipe().subscribe(
response =>{
console.log(response);
}
);
答案 1 :(得分:0)
使用Subject
存储喜爱的电影。当用户单击add to fav
时,将其添加到您喜欢的组件的myFavs
列表中。
答案 2 :(得分:0)
我想这两个组件都不共享父子关系。当您在两个互不相关的组件之间进行通信时,可以使用服务来实现。您要做的就是在您的服务中声明一个主题。
要了解该主题的工作原理,您需要对rxjs和订阅有适当的了解。基本上,声明主题时,可以从多个组件中进行订阅。默认情况下,主题的任何更改都将传达给所有订阅者,因此,它比事件发射器更好。为了保持代码的性能,您可以(并且应该)在destroy方法中取消订阅它。
此外,在实现时,请确保正在使用的服务是在两个组件的父级而不是组件级上初始化的。假设我有一个服务S,以及两个组件A和B。如果两者都有一个公共父P,那么最好在P中实例化该服务。如果它们不共享父子关系,则可以这样做。在app.module中。
主题声明:
private sub = new Subject<any>();
要更改主题,请执行以下操作:
this.sub.next({movieName:'Batman'});
要阅读此更改,您需要订阅服务中的主题。 订阅后,您可以按以下方式阅读。
this.subject.subscribe((obj) => {
console.log(obj.movieName);
})
答案 3 :(得分:0)
您可以在公共服务中使用新主题(RxJS)。之后任何组件都可以订阅该主题,接下来将使用逻辑。
使用.next()
方法发出事件。