#angular #rxjs #ngrx #spartacus-storefront
#angular #rxjs #ngrx #спартак-витрина
Вопрос:
В ngOnInit() есть Observable<> .
ngOnInit() {
this.products$ = this.someService.getMissingProducts();
}
this.products$ имеет наблюдаемый тип<Product[]>, а Product имеет поле-член code(строковый тип).
Я бы хотел изменить все кодовые значения Product[] на новые.
Извините за этот глупый вопрос. Я не силен в typescript и angular, поэтому попытался найти какое-то решение, но потерпел неудачу.
Есть ли какой-нибудь простой способ?
Заранее спасибо.
P.S. Я добавил этот код в свое решение. спасибо за Эдварда
this.products$ = this.someService.getMissingProducts().pipe(
map( product => {
return product;
}),
map((array:Product[]) => {
return array.map((item:Product) => {
blabla~
return { ...item};
});
})
);
Комментарии:
1. Я хотел бы лучше понять, чего вы пытаетесь достичь. Вы хотите создать «продукт для замены»? Или в чем причина изменения кода продукта? Простое изменение кода продукта звучит не очень хорошо.
2. Прошу прощения за то, что вызвал у вас путаницу. На самом деле, имя поля, которое я хочу изменить, было не кодом, а другим полем, доступным только для чтения. (Я только что написал имя поля ‘code’ в качестве примера) Фактическое значение целевого поля поступило с сервера api, но не было расписания для выпуска сервера api. Поэтому мне пришлось изменить значение файла в приложении angular.
3. понял, np. Подходящее место для изменения значения поля может быть в адаптерах, подробнее об этом можно прочитать на sap.github.io/spartacus-docs/connecting-to-other-systems . Но, возможно, вам не нужна такая сложность в вашем проекте. Преобразование значения в соответствии с предлагаемой нами системой адаптеров означает, что вы делаете это только один раз (при загрузке), и оно сохраняется во внутреннем хранилище.
4. Вы правы. Я должен был сделать это в адаптере. В то время я плохо понимал структуру spartacus. Спасибо за совет.
Ответ №1:
используйте оператор rxjs map
для преобразования значения наблюдаемого из одного в другое. Ссылка;
ngOnInit() {
this.products$ = this.someService.getMissingProducts().pipe(
map( payload => {
// Perform the operations you want.
return NewValue;
}
);
}
с pipe
помощью оператора вы можете использовать map
оператор для применения пользовательской логики для изменения значения наблюдаемого на что-то другое. хочу.
предполагая, что вы используете async
подписку в шаблоне HTML, вам не нужно подписываться в классе. если вы не используете асинхронный канал в шаблоне, обязательно отпишитесь в OnDestroy
Комментарии:
1. Спасибо. Я решил проблему с помощью вашей подсказки. Я отредактировал свой вопрос и добавил свое решение для таких новичков, как я.
Ответ №2:
import { Subscription } from 'rxjs';
subscription: Subscription;
ngOnInit() {
this.products$ = this.someService.getMissingProducts();
this.subscription = this.products$.subscribe((res: any) => {
this.something = res;
})
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
Несколько замечаний:
Это реализация, созданная для файла typescript.
Чтобы получить значение (значения) из observable, мы должны подписаться на него.
Когда мы подписываемся, мы сохраняем подписку и отказываемся от подписки при уничтожении (в противном случае вы вызовете утечки памяти в вашем приложении).
Существует также асинхронный канал, на случай, если вы хотите использовать observable непосредственно в вашем HTML-шаблоне: https://angular.io/api/common/AsyncPipe Например, если ваша наблюдаемая будет выводить строку, мы можем использовать ее следующим образом (с кодом из вашего примера)::
<span>Observable value is {{ productName$ | async }}</span>
Использование observable из шаблона лучше, когда это возможно, поэтому нам не нужно хранить подписку observable и не забудьте уничтожить ее, чтобы предотвратить утечки памяти.
Отмена подписки будет обработана автоматически из Angular с помощью асинхронного канала.