【问题标题】:Angular 2: get data from http in parent-component and subscribe on it nestedAngular 2:从父组件中的http获取数据并订阅它嵌套
【发布时间】:2017-01-06 21:22:28
【问题描述】:

我打算做这样的架构:

  • 组件store
  • --嵌套组件book

store - 我有一个服务调用,它从服务中获取数据,我订阅了结果。就像 angular2 文档 (http) 中描述的那样。

我想在嵌套组件中使用这些数据:在表单 (formBuilder)、材料设计元素等中。

哪种方式最好?我是 angular2 的新手。

商店:

book: IBook;

constructor(private bookService: BookService) { }

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

图书服务:

...

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 || { };
}

...

书籍:

@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?*/
});

因为,如果我在任何地方都使用 async book(不是 formBuilder) - 一切都很好,但 formBuilder 需要在父组件中加载数据后更新值。我该怎么做?

【问题讨论】:

    标签: javascript angular typescript


    【解决方案1】:

    如何将bookID 传递给BookComponent 并让BookComponent 处理ngInit 中的异步http 获取?

    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;
          });
      }
    }
    

    否则你有几个选项在https://angular.io/docs/ts/latest/cookbook/component-communication.html中解释

    我将简要强调两种我认为您可以使用的方法。

    使用 ngOnChanges 拦截输入属性更改

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

    更多信息https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

    父母和孩子通过服务进行交流

    @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;
            });
      }
    }
    

    【讨论】:

    • 你能用商店的第二种方法添加一个例子吗?请使用 http 调用...
    • 因为例如我不想调用 http:get 两次(在商店和书中) - 我想调用一次 get-method,并在任何地方使用这些数据......
    • 顺便说一句,更新表单是否是个好主意:ngOnChanges(changes: {[propKey: string]: SimpleChange}) { for (let propName in changes) { if (propName === 'book' &amp;&amp; this.bookForm) { Object.keys(this.book).forEach(k=&gt;{ let control = this.bookForm.get(k); if (control) { control.setValue(this.book[k]); } }); } } }?或者我需要其他东西来用值填充动态表单?
    猜你喜欢
    • 2021-11-18
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 2016-04-26
    • 2019-07-19
    相关资源
    最近更新 更多