2016-11-29 16 views
6

Tôi đang xây dựng ứng dụng ng2 bằng ngrx. Khi ứng dụng được khởi chạy, dịch vụ web được gọi để nhận dữ liệu ban đầu, khi dữ liệu này được tìm nạp, tôi tạo một hành động INIT_DONE.Đang chờ hành động ngrx trước khi tải trang với thông số URL

Nhà nước của tôi trông như thế này:

export interface State { 
    documents: Document[]; 
    selectedDocument: Document 
} 

Khi tôi đi đến trang/mypage/456 nơi 456 là một tham số url, tôi cần phải nhận được một số dữ liệu lấy vì vậy tôi có được các thông số URL như này:

ngOnInit() { 
    this.paramSubscription = this.route.params 
    .select<string>('id') 
    .map((id) => new SelectAction(id)) 
    .subscribe(this.store); 
} 

các SELECT_ACTION tìm thấy nguyên tố này trong các dữ liệu lấy và đặt selectedDocument. Vấn đề là SELECT_ACTION được tạo trước INIT_DONE và tại thời điểm đó documents trống.

Làm cách nào để đợi INIT_DONE trước khi tải trang của tôi?

Trả lời

6

tôi sẽ tận dụng các nhà điều hành combineLatest như nó kết hợp các giá trị mới nhất của nhiều suối nguồn. Ngoài ra tôi muốn kiểm tra kỹ xem các tài liệu đã được thiết lập chưa (ở đây tôi cho rằng đó là một mảng) bằng cách sử dụng bộ lọc.

ngOnInit() { 
    this.subscription = Observable.combineLatest(
     this.store.select("documents") 
      .filter(documents => documents.length > 0), 
     this.paramSubscription = this.route.params 
      .select<string>('id') 
) 
    .map((combinedData: [Object[], string]) => combinedData[1]) 
    .subscribe(this.store); 
} 

Đồng thời chỉ định đăng ký biến để bạn có thể hủy đăng ký khi thành phần bị hủy. Nếu không, đăng ký của bạn sẽ diễn ra sau khi thành phần đã bị hủy và có thể hành động của bạn vẫn được giải phóng:

+0

có lỗi chính tả trong _filter_ iteratee: _documents_ vs _document_. –

+0

@JakubBarczyk Cảm ơn! – chrigu

0

Bạn có thể chọn tài liệu từ các cửa hàng và đăng ký với nó và phát ra hành động của bạn từ đó:

ngOnInit() { 
    this.store.select("documents").subscribe(documents => { 
    this.paramSubscription = this.route.params 
     .select<string>('id') 
     .map((id) => new SelectAction(id)) 
     .subscribe(this.store); 
    }); 
} 
2

Bạn cần người giải quyết. Trình phân giải chờ cho đến khi dữ liệu khả dụng trước khi hoàn tất tác vụ điều hướng.

@Injectable() 
export class DocumentsResolver implements Resolve { 

    constructor(
     private store: Store 
    ) {} 

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Hero> { 
     // take id from snapshot 
     const id = route.params['id']; 
     // start with the document list 
     return this.store.select('documents') 
      // wait until there is data available 
      .filter(documents => documents && documents.length > 0) 
      // then produce the selected document 
      .mergeMapTo(this.store.select('selectedDocument')); 
    } 
} 

On cấu hình tuyến đường:

export const DocumentsRoutes: RouterConfig = [ 
    { path: 'documents/:id', component: DocumentsDetailComponent, resolve: { document: DocumentsResolver } } 
]; 

Thông tin thêm về bộ định tuyến quyết tâm here

+0

vấn đề với trình phân giải là giao diện người dùng sẽ không được hiển thị dữ liệu được tải ... chúng tôi không thể hiển thị một số tiến trình – Sreekumar

Các vấn đề liên quan