2017-08-10 50 views
1

我试图在我的ngrx存储中存储OrderState对象。我有这个问题是从我的用户界面提取数据。我只想使用异步管道从此可观察对象获取一个子属性。如何使用管道从可观察对象中提取属性

order.state.ts

export interface OrderState { 
    stage: number; 
    postcode: string; 
} 

app.component.ts

... 
export class AppComponent { 
    counter: Observable<number>; 
    readonly orderState$: Observable<OrderState>; 

    constructor(
     private appStateStore: Store<AppState>, 
     private counterActions: CounterActions, 

     private orderStateStore: Store<OrderState>, 
     private orderActions: OrderActions, 
    ) { 

    this.counter = appStateStore.select('counter'); 
    this.orderState$ = orderStateStore.select(store => store); 
    } 
... 

app.component.html

<div>Stage: {{ (orderState$ | async)?.stage }}</div> 

什t是从我的orderstate对象获取stage属性所需的语法。

如果我显示{{ orderState$ }}我只是得到[Object object]显示在页面上。

我猜可能我没有从我的商店中正确选择?


更新:我必须在这里丢失一些基本的东西。现在我已经做到了这一点,以尝试和工作发生了什么事......

app.component.ts

stage: number 

... 

    this.orderStateStore.select(s => s).subscribe((data:OrderState) => { 
     this.stage = data.stage; 
     console.log(this.stage); 
    }); 

app.component.html

<div>Stage: {{ stage }}</div> 

我可以在控制台中看到我的那个阶段报告为未定义。我相信这与问题有关。出于某种原因,我无法在此箭头功能中设置我的组件的stage


更新:此行为似乎很奇怪...

order.state.ts

export interface OrderState { 
    stage: number; 
    postcode: string; 
} 

app.component.ts

... 
this.orderStateStore.select(s => s).subscribe((data:OrderState) => {  
    console.log('--- START ---'); 
    console.log(data); 
    console.log('Stage: ' + data.stage); 
    console.log('--- END ---'); 
}); 
... 

现在这是我得到的安慰乐...

enter image description here

正如你所看到的,data实际上不是OrderState类型。它是围绕OrderState的包装类型,称为AppState。很好,所以我修改我的代码以记录data.orderState.stage以获得值1。然而,当我这样做时,TypeScript抱怨orderState不是数据的属性 - 它显然正在查看控制台输出!

+1

'{{(orderState $ | async).stage}}'<==这个语法应该工作得很好。 – Meeker

+0

可悲的是没有。不知道我做错了什么。 – Remotec

+0

您应该用您的示例创建plnkr – Meeker

回答

1

当你做{{orderState $}}时,它正在显示[对象对象],因为它将你的结果从异步管道(一个对象)转换为一个字符串。要拉开一定的属性与你想要做这样的事情

{{orderState$ | async | asyncField : 'stage'}} 

在管看起来像

@Pipe({name: 'asyncField'}) 
export class AsyncFieldPipe implements PipeTransform { 
    transform(object, key: string){ 
     return object[key]; 
    } 
} 

所以基本上你是从异步管道传递结果这条管道和返回管道一个特定的领域。这是一个工作plunkr https://plnkr.co/edit/mnsf9s2zxEypDiDDUzrp?p=preview


更新 - 作为一个管道的替代方法,您还可以使用rjxs映射方法来限制从观察到的序列返回。我喜欢这种方法,因为访问应答性能可能不如上述管一样容易,在这种情况下,更复杂的变换函数可能需要被包括在component.ts

this.orderState$ = orderStateStore.select(store => store).map(res => res.stage); 

这里是一个工作plunkr https://plnkr.co/edit/zbfuSBCLXwlMIhWCPf6z?p=preview

+0

@RemotecUk这个管道的替代方法是将rjxs .map函数添加到可观察序列.map(res => res.stage)的末尾,现在{{$ orderState}}将只是输出舞台属性 – LLai

+1

作为管道的替代品,您能否在答案中提供这个例子?谢谢。 – Remotec

+0

@RemotecUk我已更新我的回答 – LLai

0

看起来我错了从ngrx商店中选择的错误。

WRONG

this.orderState$ = orderStateStore.select(store => store); 

正确

this.orderState$ = appStateStore.select(x => x.orderState); 

这是在回顾明显。我的想法是,你可以切入你想要的商店。仅供参考我的存储对象如下:

app.state.ts

export interface AppState { 
    counter: number; 

    orderState : OrderState; 
} 

order.state.ts

export interface OrderState { 
    stage: number; 
    postcode: string; 
} 

OrderStateAppState一个 “子” 店。在我的情况下,我仍然需要参考appStateStore,但使用=>函数从对象中检索orderState