我正在Angular上制作我的第一个应用程序。我试图按性别属性过滤书籍对象列表。我在filteredData
变量和书籍列表FireBaseList
之间共享数据时遇到困难。
我正在尝试将filteredData
变量从fixed-nav.component
传递到books-grid.component
。从我的研究中,我知道我需要使books-grid.component
“ bookList”可以观察到任何更改,并使bookList
上的fixed-nav.component.ts
发出this.bookList
上任何更改的事件< / p>
但是,我无法实现这一目标。我知道已经有很多关于可观测对象的问题,但是没有一个使用Firebase。希望有任何人能帮助我,谢谢!!
我用作过滤器的fixed-nav.component
import { Component, OnInit } from '@angular/core';
import { BookService } from '../../../services/book.service';
import { Book } from '../../../models/book';
@Component({
selector: 'fixed-nav',
templateUrl: './fixed-nav.component.html',
styleUrls: ['./fixed-nav.component.css']
})
export class FixedNavComponent implements OnInit {
Genders: string[];
bookList: Book[];
constructor(private bookService: BookService) {
this.Genders = ["Historia","Literatura", "Infantil", "Juvenil","Poesía","Narrativa"];
}
filterByGender(gender: string){
this.bookService.getBooks() // FIREBASE
.snapshotChanges()
.subscribe(item => {
this.bookList = [];
item.forEach(element => {
let x = element.payload.toJSON();
x["$key"] = element.key;
this.bookList.push(x as Book)
})
const filteredData = this.bookList.filter( function(element){
return element.gender == gender;
});
return filteredData; // I WANT TO SHARE THIS DATA
})
}
ngOnInit() {
}
}
books-grid.component.ts
import { Component, OnInit } from '@angular/core';
import { BookService } from '../../services/book.service';
import { Book } from '../../models/book';
@Component({
templateUrl: './books-grid.component.html',
styleUrls: ['./books-grid.component.css']
})
export class BooksGridComponent implements OnInit {
bookList: Book[];
constructor(private bookService: BookService) {}
ngOnInit() {
this.bookService.getBooks() // FIREBASE
.snapshotChanges()
.subscribe(item => {
this.bookList = [];
item.forEach(element => {
let x = element.payload.toJSON();
x["$key"] = element.key;
this.bookList.push(x as Book)
})
// SHARED DATA HERE
})
}
}
book.service.ts
import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';
import { Book } from '../models/book'; // Model
@Injectable({
providedIn: 'root'
})
export class BookService {
bookList: AngularFireList<any>;
selectedBook: Book = new Book(); // Temporally save selected Book
constructor(private firebase: AngularFireDatabase) { }
getBooks(){
return this.bookList = this.firebase.list('books');
}
}
books.model.ts
export class Book {
$key: string;
title: string;
author: string;
gender: string;
language: string;
image: string;
likes: number;
price: number;
new: boolean;
}
答案 0 :(得分:4)
在您的book.service.ts
中创建一个filterdData
变量,然后像下面一样设置filterdData
的功能。使用Subject
import { Subject } from 'rxjs';
filteredData = new Subject<any>();
setFilteredData(data) {
this.filteredData.next(data);
}
然后在完成过滤后的fixed-nav.component.ts
中设置如下所示的过滤数据
this.bookService.setFilteredData(filteredData);
最后像下面一样从filteredData
订阅book.service.ts
中books-grid.component.ts
的{{1}}并将数据分配到所需的变量中。
constructor(private bookService: BookService) {
bookService.filteredData.subscribe((data)=>{
// Assign the data into variable that you want e.g this.filteredData = data;
})
}
希望这对您有帮助!
答案 1 :(得分:1)
您可以利用另一项共享服务,在该服务中您更新书单,然后从您的 BooksGridComponent 或需要的任何其他组件中订阅该已过滤书单的任何更改事件。我对您的代码做了一点编辑。
类似的事情:
创建一个新服务,在其中您将过滤后的BooksList作为Observable返回,以便任何组件都可以订阅它
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs'; // For rxjs 6
@Injectable({
providedIn: 'root'
})
export class SharedDataService {
private filteredBookList: Subject<Book[]> = new Subject<Book[]>();
constructor() {}
public getFilteredBookList(): Observable<Book[]> {
return this.filteredBookList.asObservable();
}
public setFilteredBookList(books: Book[]): void {
this.filteredBookList.next(books);
}
}
fixed-nav.component.ts:
在这里,您只需调用SharedDataService并设置filteredBookList。
this.sharedDataService.setFilteredBookList(filteredData);
现在在您的books-grid.component.ts中:
在这里,您将订阅filteredBookList的所有更改
this.sharedDataService.getFilteredBookList().subscribe((books: Book[]) => {
// Do Something with the filtered BookList from SharedDataService
})