以编程方式使用AsyncPipe-Angular 2
我使用一个组件来呈现类似于表的数据,我给它列的列表,数据,数据如何映射到每一列,最后是应用到每一列数据的管道列表 到目前为止,唯一的问题是当其中一个管道是异步管道时 经过一段时间的实验,我发现当在模板上使用asyncpipe时,转换方法会被多次调用。然而,如果我以编程方式使用它,转换方法只会被调用一次(在我调用它的时候) 我猜在模板上多次调用它的原因是因为它是一个不纯净的管道,但我如何通过编程处理它呢 下面是一个演示我刚才所说的:以编程方式使用AsyncPipe-Angular 2,angular,angular-pipe,Angular,Angular Pipe,我使用一个组件来呈现类似于表的数据,我给它列的列表,数据,数据如何映射到每一列,最后是应用到每一列数据的管道列表 到目前为止,唯一的问题是当其中一个管道是异步管道时 经过一段时间的实验,我发现当在模板上使用asyncpipe时,转换方法会被多次调用。然而,如果我以编程方式使用它,转换方法只会被调用一次(在我调用它的时候) 我猜在模板上多次调用它的原因是因为它是一个不纯净的管道,但我如何通过编程处理它呢 下面是一个演示我刚才所说的: @Injectable() export class Async
@Injectable()
export class AsyncProvider {
constructor() {}
getById(id: number) {
// Just some mock data
return Observable.of({id, times_five: id*5}).delay(1000);
}
}
@Component({
selector: 'my-app',
providers: [AsyncPipe, AsyncProvider]
template: `
<div>
<p>Template async pipe</p>
<p>{{ asyncObj | async | json }}</p>
<hr>
<p>Programmatically async pipe</p>
<p>{{ asyncObjPiped | json }}</p>
</div>
`,
directives: []
})
export class App {
constructor(
private _provider: AsyncProvider,
private _async: AsyncPipe
) {
this.asyncObj = this._provider.getById(123);
this.asyncObjPiped = this._async.transform(this.asyncObj);
}
}
没有任何成功:(经过一番努力,我终于取得了一些成果,以下是我必须做的,以供将来参考 第一种方法: 请注意,需要一个新变量(new_asyncObj),因为finally似乎返回一个新对象,而不是修改现有对象。 而重复(2)之后的最后一次,所以它会打开承诺
第二种方法: 每500毫秒重新计算一次管道,简单有效,尽管我期待更好的结果
最后方法: 使用NgZone和ChangeDetectorRef似乎也能很好地工作,甚至考虑到一些丑陋的黑客行为,比如两次调用AsyncPipe来打开值
无论如何,希望它能真正帮助那些在以编程方式处理非纯管道方面感到沮丧的人
欢迎您提供任何建议或更好的答案!以编程方式处理它意味着什么?您想做什么?@AJT_82我希望它的行为就像我在模板中使用管道一样(有关详细信息,请参阅plunker),但是,因为asyncPipe的工作方式(此处提供src代码:)为了发出正确的结果,必须多次调用管道。这似乎是asyncpipe不是纯管道的原因,但我也不知道如何“模拟”这种非纯行为是在控制器上通过编程实现的,我也不知道它在angular代码中的位置。我喜欢使用异步管道的想法,因为它会触发OnPush更改检测(手动订阅则不会)。通常,你需要在一个方法中使用观察到的变量。给你一个a,让它发挥作用。尽管如此……如果有一个更干净、更有文档记录的方法,那就太好了。
export class App {
constructor(
private _provider: AsyncProvider,
private _async: AsyncPipe,
private _ref: ChangeDetectorRef,
) {
this.asyncObj = this._provider.getById(123);
this.asyncObjPiped = this._async.transform(this.asyncObj);
setInterval(() => {
this._ref.detectChanges();
}, 1000);
}
}
export class App {
constructor(
private _provider: AsyncProvider,
private _async: AsyncPipe,
) {
this.asyncObj = this._provider.getById(123)
let processPipe = () => {
this.asyncObjPiped = this._async.transform(new_asyncObj);
}
let new_asyncObj = this.asyncObj.finally(processPipe).repeat(2);
processPipe();
}
}
export class App {
constructor(
private _provider: AsyncProvider,
private _async: AsyncPipe,
) {
this.asyncObj = this._provider.getById(123)
setInterval(() => {
this.asyncObjPiped = this._async.transform(this.asyncObj);
}, 500);
}
}
export class App {
constructor(
private _provider: AsyncProvider,
private _async: AsyncPipe,
private _ref: ChangeDetectorRef,
private zone: NgZone,
) {
this.asyncObj = this._provider.getById(123)
this.zone.onMicrotaskEmpty
.subscribe(() => {
this.asyncObjPiped = this._async.transform(this.asyncObj);
this.asyncObjPiped = this._async.transform(this.asyncObj);
this._ref.detectChanges();
});
}
}