我已经习惯了ngrx-store,但是为了摆脱样板,我决定使用ngrx-data。Ngrx-data 文档有一点限制,我很难找到实现 odata 模式的方法。
正如你在这里看到的,ngrx Entity DataService 有一个休息模式,所以它发送一个 put 像PUT api/heroes/1
:但在 odata 模式中,您应该这样做:PUT api/heroes(1)
.
除此之外,我们在 OData 中还有使用 api 的函数和操作,例如:
GET api/heroes/Default.GetMostPowerful(minimumPower=5)
.
此外,我们还有 Odata 的返回模式,它是一个包含数据的包装器,如下所示:
{
"@odata.context": "http://localhost:57003/api/v2/$metadata#Users",
"value": [
{
"id": 1,
"mail": "foo@foo.com",
"displayName": "foo, Adam "
},
{
"id": 2,
"mail": "bar@bar.com",
"displayName": "bar, Andy",
}
}
我怎样才能覆盖这一切?是否有任何服务可以扩展并提供给 Angular 以实现所有 odata 模式?
提前致谢!
- 编辑 -
感谢@Meligy,我可以执行 odata 持久性,但我仍在努力使用 odata 功能。这是我到目前为止所做的:
const getByEmail = createAction(
'[User] Get User by Email',
(payload: string) => ({ payload })
);
@Injectable({ providedIn: 'root' })
export class UserService extends EntityCollectionServiceBase<User> {
constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
super('User', serviceElementsFactory);
}
getByEmail(email: string) {
this.dispatch(getByEmail(email));
}
}
当你调用getByEmail('foo@foo.com')
它时,它会调度动作,但我不知道如何扩展effects
来调用我的扩展类,DefaultDataService
然后使用获取的数据再次调度成功动作。
我已经DefaultDataService
准备好扩展类中的函数来获取数据,但我正在尝试找到一种方法来从操作中触发它。
export class OdataService<T> extends DefaultDataService<T> {
constructor(entityName: string, protected factory: OdataServiceFactory) {
super(entityName, factory.http, factory.httpUrlGenerator);
}
protected buildRoute(id?: number) {
const route = this.factory.pluralizzer.pluralize(this.entityName);
return id
? `${environment.api}/${route}(${id})`
: `${environment.api}/${route}`;
}
protected getCollection(route: string) {
return this.http.get<any>(route).pipe(
map(data => data.value)
);
}
protected getOne(route: string) {
return this.http.get<any>(route).pipe(
map(data => {
delete data['@odata.context'];
return data;
})
);
}
protected serializeParams(params?: Dictionary<any>) {
if (!params) {
return '';
}
return Object.keys(params).map(key => `${key}=${params[key]}`).join(',');
}
getAll() {
return this.getCollection(this.buildRoute());
}
getWithQuery(params: string) {
return this.getCollection(`${this.buildRoute()}?${params}`);
}
getById(key: number) {
return this.getOne(this.buildRoute(key));
}
// this is the function method that will call my generic odata functions
// so the question is how to tell ngrx/data that my custom action should come here
getFunction(namespace: string, name: string, params?: Dictionary<any>) {
const route = this.buildRoute();
const url = `${route}/${namespace || 'Default'}.${name}(${this.serializeParams(params)})`;
return this.getOne(url);
}
}