Ich hatte den ganzen Tag zu kämpfen, um meine Angular-App mit ngrx/Geschäft 4 zu arbeiten. Nach vielen erfolglosen Stunden habe ich beschlossen, eine neue absolute minimale App zu erstellen, um zu überprüfen, ob ich vielleicht ein anderes Problem habe . Aber die minimale App funktioniert überhaupt nicht :(ngrx Geschäft 4 Wählen Sie nicht funktioniert
In den Chrome Redux Devtools kann ich sehen, dass der Laden ordnungsgemäß aktualisiert wird. Aber die Benutzeroberfläche wird nicht aktualisiert. Auch die Protokollanweisung in der app.component.ts (this.age$.subscribe(console.log)
) wird nie ausgeführt. ich habe wirklich keine Ahnung, was ich vermisst.
Hier der entsprechende Code ist.
package.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 { }
state.ts
export interface AppState {
age: number
}
export const INITIAL_STATE: AppState = {
age: 1
}
actions.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) {
}
}
reducer.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()));
}
}
app.component.html
<h3>Age: {{ age$ | async }}</h3>
<button (click)="changeAge()">Change Age</button>
Wow, das war der Trick!Vielen Dank! Ich schätze, ich würde noch ein paar Tage verschwenden, um das Problem zu finden. Meiner Meinung nach ist dies in der ngrx/store-Dokumentation nicht aussagekräftig genug erklärt. Ich würde niemals zu dem Schluss kommen, dass der Name des Reduzierers gleich dem Namen des Staates sein muss. –
Ich stimme zu, das ist verwirrend. Ich bin selbst mehrmals darüber gestolpert. – seescode