组件通过标准的 Input 和 Output 进行操作,并不直接访问 store.
import { Component, Input } from '@angular/core';import { Book } from '../models/book';@Component({ selector: 'bc-book-authors', template: `Written By:
{ { authors | bcAddCommas }} `, styles: [` h5 { margin-bottom: 5px; } `]})export class BookAuthorsComponent { @Input() book: Book; get authors() { return this.book.volumeInfo.authors; }}
import { Component, Input, Output, EventEmitter } from '@angular/core';import { Book } from '../models/book';@Component({ selector: 'bc-book-detail', template: ``, styles: [` :host { display: flex; justify-content: center; margin: 75px 0; } md-card { max-width: 600px; } md-card-title-group { margin-left: 0; } img { width: 60px; min-width: 60px; margin-left: 5px; } md-card-content { margin: 15px 0 50px; } md-card-actions { margin: 25px 0 0 !important; } md-card-footer { padding: 0 25px 25px; position: relative; } `]})export class BookDetailComponent { /** * Presentational components receieve data through @Input() and communicate events * through @Output() but generally maintain no internal state of their * own. All decisions are delegated to 'container', or 'smart' * components before data updates flow back down. * * More on 'smart' and 'presentational' components: https://gist.github.com/btroncone/a6e4347326749f938510#utilizing-container-components */ @Input() book: Book; @Input() inCollection: boolean; @Output() add = new EventEmitter { { title }} { { subtitle }} (); @Output() remove = new EventEmitter (); /** * Tip: Utilize getters to keep templates clean */ get id() { return this.book.id; } get title() { return this.book.volumeInfo.title; } get subtitle() { return this.book.volumeInfo.subtitle; } get description() { return this.book.volumeInfo.description; } get thumbnail() { return this.book.volumeInfo.imageLinks.smallThumbnail; }}