Angular 4商店可以观察到早到?

时间:2017-10-02 13:47:47

标签: angular typescript ngrx ngrx-store

我有这个应用程序,我有一个商店和一个页面组件。

拥有此页面组件:

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 $

他试图尽快添加它,我想是因为他在通话前尝试了吗?

添加图像是控制台。

console of the app

1 个答案:

答案 0 :(得分:0)

Index.ts没有正确设置,

当有相同的错误时,请检查它是否已保存在商店中。如果保存了检查选择器,因为如果它存储在商店中,您只需将其取出即可。

const rootSelectors = {
  subscriptions: createSelector(getCampaignsState, (state: SubscriptionsState) => _.get<SubscriptionsListState>(state, 'subscriptions')),
  subscription: createSelector(getCampaignsState, (state: SubscriptionsState) => _.get<SubscriptionsDetailState>(state, 'subscription'))
};