我有这个应用程序,我有一个商店和一个页面组件。
拥有此页面组件:
import {AfterViewInit, Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute, Params} from '@angular/router';
import {Store} from '@ngrx/store';
import {Translation, TranslationService} from 'angular-l10n';
import * as _ from 'lodash';
import * as moment from 'moment';
import {Observable} from 'rxjs/Observable';
import {of} from 'rxjs/observable/of';
import {Language, LoadLanguagesAction} from '../../../shared';
import {DateTimeFormatService} from '../../../shared';
import {TagsList} from '../../../shared/models/tags-list';
import * as fromRoot from '../../../shared/reducers';
import {LoadSubscriptionDetailAction, LoadSubscriptionDetailSuccessAction} from '../../actions/subscription';
import {EditSubscriptionForm} from '../../models/edit-subscription-form';
import {Subscriptions} from '../../models/subscriptions';
import * as fromSubscription from '../../reducers';
import {Subscription} from 'rxjs/Subscription';
@Component(
{ selector: 'storever-subscription-detail', templateUrl: './subscription-detail.component.html', styleUrls: ['./subscription-detail.component.scss'] })
export class SubscriptionDetailComponent extends Translation implements OnInit, OnDestroy {
subscription$: Observable<Subscriptions>;
languages$: Observable<Language[]>;
tagsList$: Observable<TagsList[]>;
first: Subscriptions;
private actionsSubscription: Subscription;
name: string;
created: string;
update: string;
createdP: string;
updateP: string;
createdS: string;
updateS: string;
constructor(private store: Store<fromSubscription.AppState>, private activatedRoute: ActivatedRoute, translation: TranslationService) {
super(translation);
this.actionsSubscription = activatedRoute.params.pluck<Params, string>('subscriptionId')
.distinctUntilChanged()
.switchMap(subscriptionId => of(new LoadSubscriptionDetailAction(subscriptionId)))
.subscribe(store);
this.subscription$ = this.store.select(fromSubscription.selectors.getSubscription);
this.languages$ = this.store.select(fromRoot.selectors.getLanguages);
this.tagsList$ = this.store.select(fromRoot.selectors.getTags);
this.subscription$.subscribe(data => (data ? console.log('dataaaaaaaaaa', data) : null ), err => console.log('err', err));
/*
this.created = moment(this.subscription$.created).format('DD/MM/YYYY h:mm:ss');
this.update = moment(this.subscription$.updated).format('DD/MM/YYYY h:mm:ss');
this.createdP = moment(this.subscription$.player.created).format('DD/MM/YYYY h:mm:ss');
this.updateP = moment(this.subscription$.player.updated).format('DD/MM/YYYY h:mm:ss');
this.createdS = moment(this.subscription$.site.created).format('DD/MM/YYYY h:mm:ss');
this.updateS = moment(this.subscription$.site.updated).format('DD/MM/YYYY h:mm:ss');
*/
}
get dateTimeWithSecondsAndTimezoneFormat(): string { return DateTimeFormatService.display.dateTimeWithSecondsAndTimezone; }
ngOnInit() {
this.store.dispatch(new LoadLanguagesAction());
}
ngOnDestroy() {
super.cancelParamSubscriptions();
this.actionsSubscription.unsubscribe();
}
saveMedia(subscriptions: EditSubscriptionForm): void {}
}
作为我的服务:
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {AppSettingsService, BaseRestService, BlockUIService, SendBackResult} from '../../shared';
import {Subscriptions} from '../models/subscriptions';
@Injectable()
export class SubscriptionService extends BaseRestService {
constructor(http: Http, appSettingsService: AppSettingsService, blockUIService: BlockUIService) { super(http, appSettingsService, blockUIService); }
protected get className(): string { return 'MediaService'; }
protected get isAnonymous(): boolean { return false; }
load(clientId: string, subscriptionId: string): Observable<SendBackResult<Subscriptions>> {
return this.get<Subscriptions>(`/clients/${clientId}/audio/subscriptions/${subscriptionId}`);
}
/*
update(clientId: string, mediaId: number, media: Media): Observable<SendBackResult<Media>> {
return this.put<Media>(`/clients/${clientId}/audio/media/commercials/${mediaId}`, media);
}
*/
}
减速器:
import {Action} from '@ngrx/store';
import * as _ from 'lodash';
import {UserContextActionTypes} from '../../shared';
import {
LoadSubscriptionDetailAction,
LoadSubscriptionDetailFailAction,
LoadSubscriptionDetailSuccessAction,
SubscriptionDetailActionTypes
} from '../actions/subscription';
import {Subscriptions} from '../models/subscriptions';
export interface SubscriptionsDetailState {
value: Subscriptions;
submitting: boolean;
}
const initialState: SubscriptionsDetailState = {
value: undefined,
submitting: false
};
export function SubscriptionDetailReducer(state = initialState, action: Action): SubscriptionsDetailState {
switch (action.type) {
case SubscriptionDetailActionTypes.LOAD_SUCCESS:
return handleLoadSuccessAction(state, action);
case SubscriptionDetailActionTypes.LOAD_FAIL:
return handleLoadErrorActions(state);
case UserContextActionTypes.CHANGE_CLIENT:
return handleChangeClientAction();
default:
return state;
}
}
function handleLoadSuccessAction(state: SubscriptionsDetailState, action: LoadSubscriptionDetailSuccessAction): SubscriptionsDetailState {
const newState = _.clone(state);
newState.value = action.payload;
return newState;
}
function handleLoadErrorActions(state: SubscriptionsDetailState): SubscriptionsDetailState {
const newState = _.clone(state);
newState.value = undefined;
return newState;
}
function handleChangeClientAction(): SubscriptionsDetailState {
return { value: undefined, submitting: false };
}
export const SubscriptionDetailSelectors = {
value: (state: SubscriptionsDetailState) => _.get<Subscriptions>(state, 'value'),
submitting: (state: SubscriptionsDetailState) => _.get<boolean>(state, 'submitting', false)
};
Reducer index.ts:
import {ActionReducerMap, createFeatureSelector, createSelector, MemoizedSelector} from '@ngrx/store';
import * as _ from 'lodash';
import * as fromRoot from '../../shared/reducers';
import {SubscriptionFilter} from '../models/subscription-filter';
import {Subscriptions} from '../models/subscriptions';
import {SubscriptionsListReducer, SubscriptionsListSelectors, SubscriptionsListState} from './subscriptions';
import {SubscriptionDetailReducer, SubscriptionDetailSelectors, SubscriptionsDetailState} from './subscription';
export interface SubscriptionsState { subscriptions: SubscriptionsListState; subscription: SubscriptionsDetailState;}
export interface AppState extends fromRoot.AppState { subscriptions: SubscriptionsState; subscription: SubscriptionsDetailState; }
export const reducers: ActionReducerMap<SubscriptionsState> = {
subscriptions: SubscriptionsListReducer,
subscription: SubscriptionDetailReducer
};
const getCampaignsState = createFeatureSelector('campaigns');
const rootSelectors = {
subscriptions: createSelector(getCampaignsState, (state: SubscriptionsState) => _.get<SubscriptionsListState>(state, 'subscriptions')),
subscription: createSelector(getCampaignsState, (state: SubscriptionsState) => _.get<SubscriptionsDetailState>(state, 'subscriptions'))
};
export interface Selectors {
getShowFilter: MemoizedSelector<AppState, boolean>;
getQuickSearch: MemoizedSelector<AppState, string>;
getFilter: MemoizedSelector<AppState, SubscriptionFilter>;
getPage: MemoizedSelector<AppState, number>;
getPageSize: MemoizedSelector<AppState, number>;
getOrderBy: MemoizedSelector<AppState, string>;
getCount: MemoizedSelector<AppState, number>;
getSubscriptions: MemoizedSelector<AppState, Subscriptions[]>;
getSubscription: MemoizedSelector<AppState, Subscriptions>;
}
export const selectors: Selectors = {
getShowFilter: createSelector(rootSelectors.subscriptions, SubscriptionsListSelectors.showFilter),
getQuickSearch: createSelector(rootSelectors.subscriptions, SubscriptionsListSelectors.quickSearch),
getFilter: createSelector(rootSelectors.subscriptions, SubscriptionsListSelectors.filter),
getPage: createSelector(rootSelectors.subscriptions, SubscriptionsListSelectors.page),
getPageSize: createSelector(rootSelectors.subscriptions, SubscriptionsListSelectors.pageSize),
getOrderBy: createSelector(rootSelectors.subscriptions, SubscriptionsListSelectors.orderBy),
getCount: createSelector(rootSelectors.subscriptions, SubscriptionsListSelectors.count),
getSubscriptions: createSelector(rootSelectors.subscriptions, SubscriptionsListSelectors.array),
getSubscription: createSelector(rootSelectors.subscription, SubscriptionDetailSelectors.value),
};
行动是:
import {Action} from '@ngrx/store';
import {type} from '../../shared';
import {Subscriptions} from '..//models/subscriptions';
export const SubscriptionDetailActionTypes = {
LOAD: type('[ Subscription] Load'),
LOAD_SUCCESS: type('[ Subscription] Load Success'),
LOAD_FAIL: type('[ Subscription] Load Fail')
};
export class LoadSubscriptionDetailAction implements Action {
readonly type = SubscriptionDetailActionTypes.LOAD;
constructor(public payload?: string) {}
}
export class LoadSubscriptionDetailSuccessAction implements Action {
readonly type = SubscriptionDetailActionTypes.LOAD_SUCCESS;
constructor(public payload?: Subscriptions) {}
}
export class LoadSubscriptionDetailFailAction implements Action {
readonly type = SubscriptionDetailActionTypes.LOAD_FAIL;
constructor(public payload?: number) {}
}
效果:
import {Injectable} from '@angular/core';
import {Response} from '@angular/http';
import {Router} from '@angular/router';
import {Actions, Effect} from '@ngrx/effects';
import {Action, Store} from '@ngrx/store';
import {TranslationService} from 'angular-l10n';
import * as _ from 'lodash';
import {ArrayResponse, BaseEffect, error, SendBackResult} from '../../shared';
import * as fromRoot from '../../shared/reducers';
import {Subscriptions} from '..//models/subscriptions';
import {SubscriptionDetailActionTypes,
LoadSubscriptionDetailFailAction,
LoadSubscriptionDetailSuccessAction,
LoadSubscriptionDetailAction} from '../actions/subscription';
import * as fromSubscriptions from '../reducers/';
import {SubscriptionService} from '../services/subscription.service';
@Injectable()
export class SubscriptionEffect extends BaseEffect {
private client$ = this.store.select(fromRoot.selectors.getCurrentClient).filter(client => !_.isEmpty(client));
@Effect()
load$ = this.actions$.ofType(SubscriptionDetailActionTypes.LOAD)
.delayWhen(() => this.client$)
.debug('Load Subscription details action received.')
.map((action: LoadSubscriptionDetailAction) => action.payload)
.withLatestFrom(this.client$)
.switchMap(([payload, client]) => this.subscriptionService.load(client.uuid, payload)
.map((result: SendBackResult<Subscriptions>) => new LoadSubscriptionDetailSuccessAction(result.data))
.catch((res: Response) => this.catchResponseError(res)));
@Effect()
loadFail$ = this.actions$.ofType(SubscriptionDetailActionTypes.LOAD_FAIL)
.debug('A server error occurred while retrieving media details.')
.map(() => error(this.translation.translate('SUBSCRIPTION_LOAD_ERROR'), this.translation.translate('TOAST_ERROR_TITLE')));
constructor(private actions$: Actions,
private store: Store<fromSubscriptions.AppState>,
private translation: TranslationService,
private subscriptionService: SubscriptionService,
router: Router) {
super(router);
}
protected handleUnhandledError(response: Response): Action { return new LoadSubscriptionDetailFailAction(response.status); }
}
到目前为止一切顺利。但是我在页面组件中调用了subscribe我没有得到console.log,更糟糕的是订阅没有加载,这意味着他不知道名字,因为它没有打印。我完全失败了。当调试有效负载总是存在时,调用发生一切正常,没有订阅this.subscription $
他试图尽快添加它,我想是因为他在通话前尝试了吗?
添加图像是控制台。
答案 0 :(得分:0)
Index.ts没有正确设置,
当有相同的错误时,请检查它是否已保存在商店中。如果保存了检查选择器,因为如果它存储在商店中,您只需将其取出即可。
const rootSelectors = {
subscriptions: createSelector(getCampaignsState, (state: SubscriptionsState) => _.get<SubscriptionsListState>(state, 'subscriptions')),
subscription: createSelector(getCampaignsState, (state: SubscriptionsState) => _.get<SubscriptionsDetailState>(state, 'subscription'))
};