2016-08-15 2 views
1

이 영역에서 경험이 부족한 Rxjs의 BehaviorSubject로 게임을 시작합니다. 지금까지는 구성 요소에서 루트 수준 매개 변수를 가져올 수 있지만 중첩 된 개체에 액세스하면 '정의되지 않은 속성 x를 읽을 수 없습니다.'라는 결과가 발생합니다.Rxjs는 행동 대상에 깊이 중첩 된 객체를 포함합니다

클래스 :

export class Basket extends X23Object { 
    public BasketId: number; 
    public UserID: number; 
    public User: User; 
    public BasketLines: BasketLine[] = []; 
} 

export class BasketLine extends X23Object { 
    public BasketLineId: number; 
    public BasketId: number; 
    public ProductId: number; 
    public Quantity: number; 
    public Product: Product; 
    public Price: number; 
    public Name: string; 
} 
export class Product extends X23Object { 
    public ProductId: number; 
    public CategoryId: number; 
    public Name: string; 
    public Code: string; 
    public Price: number; 
    public Details: string; 
    public Images: Image[]; 
    public Category: Category; 
} 

BasketBackendService

GetBasket() { 
    return this.authHttp.get(this.apiUrl + 'api/GetBasketByUser?id=' + parseInt(this.decodedJwt['userId']), { headers: contentHeaders }); 
} 

BasketService

private _lines: BehaviorSubject<BasketLine[]> = new BehaviorSubject([new BasketLine]); 
get getLines() { 
    return this._lines.asObservable(); 
} 
loadBasket() { 
    this.basketBackendService.GetBasket() 
     .subscribe(
      response => { 
       let lines = <BasketLine[]>response.json().basket.BasketLines; 

       this._lines.next(lines); 
      }, 
      error => console.log(error.text()) 
     ); 
} 

템플릿 (조각)

<tr *ngFor="let line of basketService.getLines | async"> 
    <td><img class="login-logo" src="{{ line.Product.Images[0].ThumbUrl }}" width="100%" /></td> 
    <td><a [routerLink]="['Product', { id: line.ProductId }]"> {{ line.Product.Code }} </a></td> 
    <td><a [routerLink]="['Product', { id: line.ProductId }]">{{ line.Product.Name }}</a></td> 
    <td class="text-right">{{ line.Price | currency:'GBP':true:'.2-2' }}</td> 
    <td class="text-center">{{ line.Quantity }}</td> 
    <td class="text-right">{{ line.Quantity * line.Price | currency:'GBP':true:'.2-2' }}</td> 
    <td><button (click)="DeleteLine(line.BasketLineId)">Remove</button></td> 
</tr> 

깊이 중첩 된 개체의 참조를 제거하면 예상되는 결과가 반환됩니다.

BehaviorSubject를 사용하여 여러 구성 요소를 업데이트하려고하지만 이것이 최상의 솔루션인지 확실하지 않습니다!

답변

0

코드가 나에게 잘 어울립니다. "깊은 중첩"은 예를 들어 line.Product.Code을 의미합니다. line.Quantity과 작동하는 경우 문제는 BehaviorSubject이 아니라 데이터 구조에있을 가능성이 큽니다.

당신의 특별한 용도는 무엇인지 모르겠지만 BehaviorSubject이나 async 파이프를 전혀 사용할 필요가 없습니다.

BasketService를 들어 당신은 사용할 수 있습니다

export class BasketService { 
    lines: BasketLine[]; 

    // ... 

    loadBasket() { 
     this.basketBackendService.GetBasket().subscribe(
      response => { 
       this.lines = <BasketLine[]>response.json().basket.BasketLines; 
      }, 
      error => console.log(error.text()) 
     ); 
    } 
} 

그럼 그냥 그것을 렌더링 :

<tr *ngFor="let line of basketService.lines"> 
    // ... 
</tr> 
+0

이 방법의 문제는 다른 구성 요소를 업데이트하지 않습니다. 머리글에 바구니를 표시하는 구성 요소가 있습니다.이 구성 요소는 페이지의 새로 고침 만 업데이트합니다. 바구니 데이터를 관찰 가능하게 만들고 페이지를 새로 고치지 않고도 모든 관련 구성 요소의 바구니를 업데이트하기 위해 서비스/주제 접근법을 찾고있었습니다. –

+0

변경 관리가 항상 준비가되기 전에 구성 요소를 업데이트하기 때문에 깊게 중첩 된 개체가 정의되지 않은 것으로 나타날 수 있습니다. –

+0

구성 요소를 수동으로 업데이트 할 필요가 없으며 Angular의 변경 감지로 인해 당신이하고있는 것 같지 않은 구성 요소의'ChangeDetectorRef' 참조를 만지작 거린다면 말입니다. 강제로 실행 ['Application.tick()'] (https://angular.io/docs/ts/latest/api/core/index/ApplicationRef-class.html#!#tick-anchor) 메소드를 시도 할 수 있습니다 변경 감지를 실행하지만이 방법이 도움이 될지 의심 스럽습니다. 나는 데이터가 다른 구조를 가지고 있다고 생각한다. '{{line | json}}'. – martin

관련 문제