簡體   English   中英

ngrx 商店 4 選擇不起作用

[英]ngrx store 4 select not working

我一整天都在努力讓我的 Angular 應用程序與 ngrx/store 4 一起工作。在很多時間不成功之后,我決定創建一個新的絕對最小的應用程序來檢查我是否還有其他問題。 但是最小的應用程序根本不起作用:(

在我可以看到的 Chrome Redux devtools 中,商店已正確更新。 但是UI沒有更新。 此外, app.component.ts ( this.age$.subscribe(console.log) ) 中的日志語句永遠不會執行。 我真的不知道我錯過了什么。

這是相關的代碼。

包.json

{
  "dependencies": {
    "@angular/animations": "^4.2.4",
    "@angular/common": "^4.2.4",
    "@angular/compiler": "^4.2.4",
    "@angular/core": "^4.2.4",
    "@angular/forms": "^4.2.4",
    "@angular/http": "^4.2.4",
    "@angular/platform-browser": "^4.2.4",
    "@angular/platform-browser-dynamic": "^4.2.4",
    "@angular/router": "^4.2.4",
    "@ngrx/store": "^4.0.2",
    "@ngrx/store-devtools": "^4.0.0",
    "rxjs": "^5.4.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@types/node": "^8.0.22",
    "typescript": "^2.4.2"
  }
}

app.module.ts

import { AppState } from './state';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools'
import { reducer } from './reducer';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    StoreModule.forRoot({ reducer }),
    StoreDevtoolsModule.instrument(),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

狀態.ts

export interface AppState {
  age: number
}

export const INITIAL_STATE: AppState = {
  age: 1
}

動作.ts

import { Action } from '@ngrx/store';

export const ACTION_TYPE = 'CHANGE_AGE_ACTION';

export class ChangeAgeAction implements Action {
  readonly type: string = ACTION_TYPE;

  constructor(public payload?: number) {
  }
}

減速機.ts

import { ChangeAgeAction } from './actions';
import { Action } from '@ngrx/store';
import { AppState, INITIAL_STATE } from './state';
import { ACTION_TYPE } from './actions';

function changeName(state: AppState, action: ChangeAgeAction): AppState {
  return {
    age: action.payload
  }
}

export function reducer(state: AppState = INITIAL_STATE, action: Action) {
  switch (action.type) {
    case ACTION_TYPE:
      return changeName(state, action);

    default:
      return state;
  }
}

app.component.ts

import { ChangeAgeAction } from './actions';
import { AppState } from './state';
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Store } from '@ngrx/store';
import { map } from 'rxjs/operator/map';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  age$: Observable<number>;

  constructor(private store: Store<AppState>) {
    this.age$ = this.store.select<number>(state => state.age);
    this.age$.subscribe(console.log);
  }

  changeAge() {
    this.store.dispatch(new ChangeAgeAction(Math.random()));
  }
}

應用程序組件.html

<h3>Age: {{ age$ | async }}</h3>
<button (click)="changeAge()">Change Age</button>

您的應用狀態建模不正確。 實際上有一個包含您的年齡的 reducer 對象。 這是我為使應用程序正常工作所做的更改:

在 state.ts

export interface AppState {
  reducer: {
    age: number
  }
}

在應用程序組件中:

export class AppComponent {
  age$: Observable<number>;

  constructor(private store: Store<AppState>) {
    this.age$ = this.store.select<number>(state => state.reducer.age);
    this.age$.subscribe(console.log);
  }

  changeAge() {
    this.store.dispatch(new ChangeAgeAction(Math.random()));
  }
}

請注意,您的 AppState 中有“reducer”對象的原因是因為當您設置這樣做時: StoreModule.forRoot({ reducer }) 它從減速器中獲取“減速器”名稱。

換句話說,如果您執行類似StoreModule.forRoot({ ageReducer })那么您的應用程序狀態將如下所示:

export interface AppState {
  ageReducer: {
    age: number
  }
}

這是代碼的工作版本:

https://stackblitz.com/edit/angular-jxszwh

另請注意,如果您使用的是 angular 異步管道,則無需在可觀察對象上調用 .subscribe 。 異步管道處理訂閱/取消訂閱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM