代码之家  ›  专栏  ›  技术社区  ›  skinnedpanda Dave

如何处理角度6中两个可见光的数据?

  •  0
  • skinnedpanda Dave  · 技术社区  · 7 年前

    我已经完成了《英雄之旅》教程(两次)和布拉德·特拉弗西的前后角。我有一点Python的(函数)经验,但我仍在努力研究角度语法和类的工作方式。

    作为实践,我正在制作一个基于ToH的图书馆web应用程序,我可以使用不同的服务将书籍和作者存储在不同的组件中,通过HTTP服务获取它们。

    跟随 Angular Style Guide 关于将逻辑放在组件中,而不是放在模板中,我已经 制作一个组合的book/author视图组件,显示作者以及他们分别写了哪些书,反之亦然(我不想把它放在HTML模板中。)

    这是你的名字 作者.component.ts 图书.component.ts 相同,但作者替换为“book/books”:

    import { Component, OnInit } from '@angular/core';
    import { Author } from '../../models/author';
    import { AuthorService } from '../../services/author.service';
    
    @Component({
      selector: 'app-authors',
      templateUrl: './authors.component.html',
      styleUrls: ['./authors.component.css']
    })
    export class AuthorsComponent implements OnInit {
      authors: Author[];
    
      constructor(private authorService: AuthorService) { }
    
      ngOnInit() {
        this.getAuthors();
      }
    
      getAuthors(): void {
        this.authorService.getAuthors().subscribe(authors =>  
          this.authors = authors);
      }
    

    这本书/AuthorService类似于《英雄之旅》的“HeroService”,因为它们使用http.get:

    /** GET authors from the server */
    getAuthors (): Observable<Author[]> {
       return this.http.get<Author[]>(this.authorsUrl);
    

    作者.ts & 书籍.ts

    export class Author {
      id: number;
      firstName: string;
      lastName: string;
      booksAuthored?: number[];
    }
    
    export class Book {
      id: number;
      authorId?: number;  // TODO: allow multiple authors
      title: string;
    }
    

    我可能已经正确理解了observable是一个stream对象(而不是JSON类型的对象),不能像常规数组那样被切片。

    我想要一个可以连接author.lastName&的函数;author.firstName,然后列出属于各自作者的书籍。我已经能够在HTML模板中使用ngFor(let author of authors)实现这一点&ngIf(如果book.authorId===author.id),但现在我想在组件(或服务)内部执行相同的操作

    2 回复  |  直到 7 年前
        1
  •  0
  •   Ruben Vermeulen    7 年前

    combineLatest 可观察的可能就是你想要的。

    所以我们把两条流结合在一起:作者和书籍。重要的是要知道,只有当authors流和books流本身都有事件时,组合流才会开始发送事件。

    接下来我们要操纵结果。所以我们使用 map books 属性添加与作者id匹配的所有书籍。

    通过这个结果流,您可以创建一个组件,显示作者及其相应书籍的列表。

    import {combineLatest} from 'rxjs';
    
    combineLatest(authors$, books$).pipe(
        map(([authors, books]) => {
            return authors.map(author => {
                return {
                    name: author.firstName + ' ' + author.lastName,
                    books: books.filter(book => book.authorId === author.id)
                };
            })
        })
    ).subscribe(res => console.log(res));
    

    组合测试

    http://rxmarbles.com/#combineLatest

    http://reactivex.io/documentation/operators/combinelatest.html

        2
  •  0
  •   K Adrian    7 年前

    你可以在Author类中添加一个函数来允许连接,

    export class Author {
      id: number;
      firstName: string;
      lastName: string;
      booksAuthored?: number[];
    
      public fullName() {
        return this.firstname + ' ' + this.lastname;
      }
    }
    

    然后只要有Author对象,就调用Author.fullname()

    要获取每个作者的书籍,可以在get authors方法中执行以下操作:

      getAuthors(): void {
        this.authorService.getAuthors().pipe(map(eachAuthor => {
           eachAuthor.booksAuthorWrote = this.bookService.getBooks<Book[]>(eachAuthor.id);
        }))
        .subscribe(authors =>  
          this.authors = authors
        );
      }
    

    这将检索getAuthors()调用返回的每个作者的书籍。如果要避免进行那么多服务器调用,只需获取所有作者和所有书籍,并运行与模板中使用的内容类似的循环:

    for(let author of this.authors) {
      for(let book of this.books) {
        if(book.authorID === author.id) {
          this.authors.booksAuthorWrote.push(book);
        }
      }
    }
    

    这假设您向author类添加了一个图书数组,如下所示:

    export class Author {
      id: number;
      firstName: string;
      lastName: string;
      booksAuthored?: number[];
      booksAuthorWrote?: Book[];
    }
    
    推荐文章