Я уже привык к ngrx-store, но, чтобы убежать от шаблона, я решил go с ngrx-data. Документация по Ngrx - это небольшой предел, и я сталкиваюсь с трудностями при поиске способа реализации шаблона одататы.
Как вы можете видеть здесь , ngrx Entity DataService имеет шаблон отдыха, поэтому отправляет пут типа: 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, которая будет реализовывать все шаблоны оддатов?
Заранее спасибо!
- РЕДАКТИРОВАТЬ -
Спасибо @Meligy, я могу выполнять постоянство одат, но я все еще борюсь с функцией одатата. Это то, что я сделал до сих пор:
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);
}
}