问题
I am busy with MeteorJS and RxJS, which is exiting but also a bit confusing sometimes. My current question is an Angular NgRx question only, not related to MeteorJS.
As you can see in the example, there is a ngIf
based on showChannels
. This boolean is set to false
. However, the async for loop inside is referenced to my store.select.
However, operators in the pipe are never executed, because of the ngIf. It seems to be a deadlock.
How do I enable the subscription to start working?
When I do a search it adds Channels to the store, and the store.select
would work if there would be no ngIf
around the ngFor
loop.
When I recplace the if to *ngIf="(channels$ | async) ?.length !== 0"
it will work, but then the tap
is run twice when I do one search.
The commented store.select with the subscribe actually works well using the markForCheck
. Any suggestions on what the best solution while not using the subscribe
?
@Component({
selector: 'podcast-search',
changeDetection: ChangeDetectionStrategy.OnPush, // turn this off if you want everything handled by NGRX. No watches. NgModel wont work
template: `
<h1>Podcasts Search</h1>
<div>
<input name="searchValue" type="text" [(ngModel)]="searchValue" ><button type="submit" (click)="doSearch()">Search</button>
</div>
<hr>
<div *ngIf="showChannels">
<h2>Found the following channels</h2>
<div *ngFor="let channel of channels$ | async" (click)="loadChannel( channel )">{{channel.trackName}}</div>
</div>
`,
})
export class PodcastSearchComponent implements OnInit, OnDestroy {
channels$: Observable<Channel[]>;
searchValue: string;
showChannels = false;
constructor(
private store: Store<fromStore.PodcastsState>,
) {}
ngOnInit() {
this.channels$ = this.store.select(fromStore.getAllChannels).pipe(
filter(channels => !!channels.length),
// channels.length should always be truthy at this point
tap(channels => {
console.log('channels', !!channels.length, channels);
this.showChannels = !!channels.length;
}),
);
// this.store.select( fromStore.getAllChannels ).subscribe( channels =>{
// console.log('channels', !!channels.length, channels);
// this.channels$ = of ( channels );
// this.showChannels = !!channels.length;
// this.ref.markForCheck();
// } );
}
doSearch() {
console.log( 'search', this.searchValue );
this.store.dispatch( new fromStore.LoadChannels( this.searchValue ) );
}
回答1:
Use the ngIf as syntax
*ngIf="channels$ | async as channels"
回答2:
If you have multiple subscriptions and they are not nested you can also use share or shareReplay(1). If all of the subscriptions are done at the same time go with share
otherwise you should use shareReplay(1)
.
来源:https://stackoverflow.com/questions/51536817/store-select-not-running-because-of-ngif-statement