rxjs - 我无法获取NgRx数据来触发API调用

标签 rxjs ngrx angular-ngrx-data

我正在尝试使用覆盖EntityData getAll()函数的服务来设置NgRx数据,以便我可以调用API。但是当我调用EntityService.getAll()时没有任何 react

entity-metadata.ts:EntityMetadataMap的标准定义,其中我定义了一个名为PageLoadData的实体

import { EntityMetadataMap } from '@ngrx/data';

export const entityMetadata : EntityMetadataMap = {
    PageLoadData: {
        entityDispatcherOptions: {
            optimisticUpdate: true
        }
    }
} 

我的AppModule.ts
import { AppResolver } from './app.resolver';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { EntityDataModule, EntityDataService } from '@ngrx/data';
import { StoreModule } from '@ngrx/store';
import { AboutUsComponent } from './about-us/about-us.component';
import { TryAtHomeComponent } from './try-at-home/try-at-home.component';
import { ContactComponent } from './contact/contact.component';
import { DesignersComponent } from './designers/designers.component';
import { PolicyComponent } from './policy/policy.component';
import { HowItWorksComponent } from './how-it-works/how-it-works.component';
import { FooterComponent } from './footer/footer.component';
import { GiftCardComponent } from './gift-card/gift-card.component';
import { HeaderComponent } from './header/header.component';
import { HomeComponent } from './home/home.component';
import { EffectsModule } from '@ngrx/effects';
import { HttpClientModule } from '@angular/common/http';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { environment } from '../environments/environment';
import { PageLoadDataDataService } from './services/page-load-data.service';
import { PageLoadDataEntityService } from './services/page-load-entity.service';
import { entityMetadata } from './entity-metadata';
@NgModule({
  declarations: [
    AppComponent,
    AboutUsComponent,
    TryAtHomeComponent,
    ContactComponent,
    DesignersComponent,
    PolicyComponent,
    HowItWorksComponent,
    FooterComponent,
    GiftCardComponent,
    HeaderComponent,
    HomeComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    EntityDataModule.forRoot({
      entityMetadata: entityMetadata
    }),
    StoreModule.forRoot({}),
    EffectsModule.forRoot([]),
    StoreDevtoolsModule.instrument({maxAge: 25, logOnly: environment.production}),
  ],
  providers: [PageLoadDataDataService, AppResolver, PageLoadDataEntityService],
  bootstrap: [AppComponent]
})
export class AppModule { 

  constructor(
    entityDataService: EntityDataService,
    pageLoadDataService : PageLoadDataDataService,
  ) {
    entityDataService.registerService('PageLoadData', pageLoadDataService); // <-- register it
  }

}


page-load-entity-service.ts:我遵循NgRx Data的标准文档并创建了如下服务:
import { Injectable } from "@angular/core";
import { EntityCollectionServiceBase, EntityCollectionServiceElementsFactory } from "@ngrx/data";
import {PageLoadData } from '../user/model/user.model';

@Injectable({ providedIn: 'root' })
export class PageLoadDataEntityService extends EntityCollectionServiceBase<PageLoadData> {
    constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
        super('PageLoadData', serviceElementsFactory)
    }
}

page-load-data.service.ts:创建了此服务以覆盖DefaultDataService的getAll功能。
import { PageLoadData } from './../user/model/user.model';
import { HttpClient } from '@angular/common/http';
import { Injectable } from "@angular/core";
import { DefaultDataService, HttpUrlGenerator, Logger } from "@ngrx/data";
import { Observable } from 'rxjs';
import {map} from 'rxjs/operators'

@Injectable({ providedIn: 'root' })
export class PageLoadDataDataService extends DefaultDataService<PageLoadData> {
    constructor(http: HttpClient, httpUrl : HttpUrlGenerator, logger: Logger) {
        super('PageLoadData' , http, httpUrl);
        logger.log('in PLD Data Service');
        //if i subscribe here to getAll api works fine the issue is somewhere else in the set up
    }
    getAll(): Observable<PageLoadData[]> {
        return this.http.get<PageLoadData[]>('https://staging-api.designer-24.com/page/home?storeId=1')
    }
}

app.resolver.ts:加载EntityService时,我使用解析器调用getAll
import { Injectable } from "@angular/core";
import { Resolve, RouterStateSnapshot, ActivatedRouteSnapshot } from "@angular/router";
import { Observable } from "rxjs";
import { tap, filter, first } from "rxjs/operators";
import { PageLoadDataEntityService } from './services/page-load-entity.service';

@Injectable()
export class AppResolver implements Resolve<boolean> {
    constructor(private pageLoadService: PageLoadDataEntityService) {}
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<boolean> {
        return this.pageLoadService.loaded$.pipe(
            tap(loaded => {
                console.log(loaded)
                if(!loaded) {
                    console.log('calling get all');
                    this.pageLoadService.getAll();   
                }
            }),
            filter(loaded => !!loaded),
            first()
        )
    }
}  

app.routing.module.ts
import { AppComponent } from './app.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppResolver } from './app.resolver';


const routes: Routes = [
  {
    path: '',
    // loadChildren: () => import('./user/user.module').then(m => m.UserModule),
    component: AppComponent,
    resolve: {
      pageLoadData: AppResolver
    }
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

这是我的应用程序组件:
import { PageLoadDataEntityService } from './services/page-load-entity.service';
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { User, PageLoadData, HomeData } from './user/model/user.model';
import { map } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less']
})
export class AppComponent {
  title = 'd24-web';
  data$: Observable<PageLoadData[]>;
  constructor(private userEntity : PageLoadDataEntityService) {
    this.data$ = userEntity.entities$.pipe(
        map(data => {
          console.log(data);
          return data
        })
    );
  }
}

应用程序组件html

<span *ngIf="(data$ | async) as data" >{{data}}</span>
<router-outlet></router-outlet>

这是redux检查器:

screenshot of redux events

即使我尝试从解析器中进行订阅,也不会调用任何API,也不会触发任何错误。我不明白为什么。但是在redux检查器中,getAll被触发,但是它的灰色。不确定那是什么意思

github链接在这里:https://github.com/rmoubayed/ngrx-data-test-env(如果有人想克隆并尝试)。

最佳答案

我找到了解决此问题的方法。我设置中的所有内容都是合法的,绝没有以任何方式错误地实现。
事实证明,我需要在EntityDataModule之前加载StoreModule和Effects!

  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    // EntityDataModule.forRoot({ // removed it from here
    //   entityMetadata: entityMetadata
    // }),
    StoreModule.forRoot({}),
    StoreDevtoolsModule.instrument({maxAge: 25, logOnly: environment.production}),
    EffectsModule.forRoot([]),
    EntityDataModule.forRoot({ // and put it here
      entityMetadata: entityMetadata
    }),
  ],

之后,一切又恢复正常了! HAYSTACK中的文字针:)
希望这对遇到相同问题的其他人有所帮助:D

关于rxjs - 我无法获取NgRx数据来触发API调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58287973/

相关文章:

angular - 为 ngrx/data 实体创建选择器

angular - @ngrx/data - 如何扩展集合缩减器/替换对数据服务调用结果的处理?

Angular6 rxjs 取消订阅定时器订阅 OnDestroy 不起作用?

rxjs - RXJS 中的 AsyncSubject 有什么意义?

angular - 何时在 angular2 中使用 ngrx/effect

javascript - ngrx/effects 库的用途是什么?

Angular 4 : Using HTTP interceptor + RxJS timeout operator error

javascript - 同一 flatMap 方法中的多个 http 请求

angular - ngrx 商店选择器在从自定义库导入应用程序时失败