简体   繁体   中英

Angular 2: get data from http in parent-component and subscribe on it nested

I plan to do such architecture:

  • component store
  • -- nested-component book

in store - i have an service call, which get data from service, and i do a subscription on result. Like it was described in angular2 docs (http).

And i want to use this data in nested components: in forms ( formBuilder ), in material-design elements etc.

Which way is the best, to do this? I'm new to angular2.

Store:

book: IBook;

constructor(private bookService: BookService) { }

ngOnInit() {
    this.bookService.getBook('1')
        .subscribe((book) => {
            this.book = book;
        });
}

BookService:

...

getBook (id): Observable<IBook> {
    return this.http.get(this.url + '/' + id)
        .map(this.extractData)
        .catch(this.handleError);
}

private extractData(res: Response) {
    let body = res.json();
    return body || { };
}

...

Book:

@Input() book:IBook;

constructor() {}

ngOnInit() {
    /*How here can i subscribe on book http data get?, so that i can use async value in forms etc?*/
});

Because, if i use async book everywhere (not formBuilder) - all is ok, but formBuilder is in need to update values, after data is loaded in parent component. How can i do this?

What about passing the bookID to the BookComponent and letting the BookComponent handle the async http get in ngInit ?

export class Book implements OnInit {
  @Input() bookID: number;
  private book: IBook;

  constructor(private bookService: BookService) {}

  ngOnInit() {
    this.bookService.getBook(this.bookID)
      .subscribe((book) => {
        this.book = book;
      });
  }
}

Otherwise you have a few options which are explained in https://angular.io/docs/ts/latest/cookbook/component-communication.html

I'll briefly highlight two ways which I think you could use.

Intercept input property changes with ngOnChanges

export class Book implements OnChanges {
  @Input() book: IBook;
  ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
    for (let propName in changes) {
       // handle updates to book
    }
  }
}

more info https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

Parent and children communicate via a service

@Injectable()
export class BookService {
  books = new Subject<IBook>();

  getBook(id): Observable<IBook> {
    return this.http.get(this.url + '/' + id)
    .map(d => {
      let book = this.extractData(d);
      this.books.next(book);
      return book;
    })
    .catch(this.handleError);
  }
  ...
}

@Component({
  selector: 'book',
  providers: []
})
export class Book implements OnDestroy {
  book: IBook
  subscription: Subscription;

  constructor(private bookService: BookService) {
    this.subscription = bookService.books.subscribe(
      book => {
        this.book = book;
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

@Component({
  selector: 'store',
  providers: [BookService]
})
export class Store {
  book: IBook;

  constructor(private bookService: BookService) { }

  ngOnInit() {
    this.bookService.getBook('1')
        .subscribe((book) => {
            this.book = book;
        });
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM