我是一個開發Angular應用程序的新手。現在,我有一個簡單的應用程序,它可以很好地與服務一起工作,但我試圖使用ngrx/store來控制某些事件。ngrx-store導入錯誤導致懶惰
那麼,我不想在熱切的組件上使用ngrx/store,而是懶洋洋地。 該項目的結構是:
app
| --control-panel
|--spaces
應用是懶散地加載控制面板,其慢速地裝載空間的根。
我收到的錯誤根本沒有幫助我。以下是錯誤:
ERROR Error: Uncaught (in promise): Error: StaticInjectorError[ReducerManager]: StaticInjectorError[ReducerManager]: Null InjectorError: No provider for ReducerManager!
下面是相關代碼:
的package.json
{
"name": "condo-control",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/animations": "^5.0.1",
"@angular/common": "^5.0.1",
"@angular/compiler": "^5.0.1",
"@angular/core": "^5.0.1",
"@angular/forms": "^5.0.1",
"@angular/http": "^5.0.1",
"@angular/platform-browser": "^5.0.1",
"@angular/platform-browser-dynamic": "^5.0.1",
"@angular/router": "^5.0.1",
"@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.5",
"@ngrx/store": "^4.1.1",
"bootstrap": "^4.0.0-beta.2",
"core-js": "^2.4.1",
"firebase": "^4.6.1",
"font-awesome": "^4.7.0",
"rxjs": "^5.5.2",
"zone.js": "^0.8.14"
},
"devDependencies": {
"@angular/cli": "^1.5.0",
"@angular/compiler-cli": "^5.0.1",
"@angular/language-service": "^5.0.1",
"@types/jasmine": "~2.5.53",
"@types/jasminewd2": "~2.0.2",
"@types/node": "~6.0.60",
"codelyzer": "~3.2.0",
"jasmine-core": "~2.6.2",
"jasmine-spec-reporter": "~4.1.0",
"karma": "~1.7.0",
"karma-chrome-launcher": "~2.1.1",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.1.2",
"ts-node": "~3.2.0",
"tslint": "~5.7.0",
"typescript": "^2.4.2"
}
}
AppModule.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { StoreModule } from '@ngrx/store/src/store_module';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './core/header/header.component';
import { FullBodyComponent } from './core/full-body/full-body.component';
import { FooterComponent } from './core/footer/footer.component';
import { ExploreComponent } from './core/full-body/explore/explore.component';
import { ContactComponent } from './core/full-body/contact/contact.component';
import { HomeComponent } from './core/home/home.component';
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
FullBodyComponent,
FooterComponent,
ExploreComponent,
ContactComponent,
HomeComponent
],
imports: [
HttpClientModule,
BrowserModule,
CommonModule,
NgbModule.forRoot(),
AppRoutingModule,
StoreModule.forRoot({})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
SpacesModule.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { StoreModule } from '@ngrx/store';
import { SpacesWelcomeComponent } from './spaces-welcome/spaces-welcome.component';
import { SpaceEditComponent } from './space-edit/space-edit.component';
import { SpacesListComponent } from './spaces-list/spaces-list.component';
import { SpaceDetailComponent } from './space-detail/space-detail.component';
import { SpacesComponent } from './spaces.component';
import { SpacesRoutingModule } from './spaces-routing.module';
import { SpaceItemComponent } from '../spaces/spaces-list/space-item/space-item.component';
import { spacesReducers } from './store/spaces.reducers';
@NgModule({
imports: [
FormsModule,
CommonModule,
SpacesRoutingModule,
StoreModule.forFeature('spaces', spacesReducers)
],
declarations: [
SpacesComponent,
SpaceDetailComponent,
SpacesListComponent,
SpaceEditComponent,
SpacesWelcomeComponent,
SpaceItemComponent
]
})
export class SpacesModule {}
個
SpacesReducers.ts
import * as SpacesActions from './spaces.actions';
import { Space } from '../../shared/space.model';
export interface FeatureState {
spaces: State;
}
export interface State {
spaces: Space[];
}
const initialState: State = {
spaces: [
new Space('Churrasqueira', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
new Space('Churrasqueira2', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
new Space('Churrasqueira3', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
new Space('Churrasqueira3', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
new Space('Churrasqueira3', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
new Space('Churrasqueira3', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg'),
new Space('Churrasqueira4', 'https://br.habcdn.com/files/dynamic_content/churrasqueira-3-em-1-1300623_big.jpg')
]
};
export function spacesReducers(state = initialState, action: SpacesActions.SpacesActions) {
switch (action.type) {
case SpacesActions.ADD_SPACE:
return {
...state,
spaces: [...state.spaces, action.payload]
};
case SpacesActions.UPDATE_SPACE:
const space = state.spaces[action.payload.index];
const updatedRecipe = {
...space,
...action.payload.updatedSpace
};
const spaces = [...state.spaces];
spaces[action.payload.index] = updatedRecipe;
return {
...state,
spaces: spaces
};
case SpacesActions.DELETE_SPACE:
const deletedSpaces = [state.spaces];
deletedSpaces.splice(action.payload, 1);
return {
...state,
spaces: deletedSpaces
};
default:
return state;
}
}
SpacesActions.ts
import { Action } from '@ngrx/store';
import { Space } from '../../shared/space.model';
export const ADD_SPACE = 'ADD_SPACE';
export const UPDATE_SPACE = 'UPDATE_SPACE';
export const DELETE_SPACE = 'DELETE_SPACE';
export class AddSpace implements Action {
readonly type = ADD_SPACE;
constructor(public payload: Space) {}
}
export class UpdateSpace implements Action {
readonly type = UPDATE_SPACE;
constructor(public payload: {index: number, updatedSpace: Space}) {}
}
export class DeleteSpace implements Action {
readonly type = DELETE_SPACE;
constructor(public payload: number) {}
}
export type SpacesActions = AddSpace | UpdateSpace | DeleteSpace;
SpacesList.component.ts
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Store } from '@ngrx/store';
import { Subscription } from 'rxjs/Subscription';
import { Observable } from 'rxjs/Observable';
import { Space } from './../../shared/space.model';
import { SpacesService } from '../spaces.service';
import * as fromSpaces from '../store/spaces.reducers';
@Component({
selector: 'app-spaces-list',
templateUrl: './spaces-list.component.html',
styleUrls: ['./spaces-list.component.scss']
})
export class SpacesListComponent implements OnInit, OnDestroy {
spacesState: Observable<fromSpaces.State>;
// spaces: Space[];
private addMode = false;
subscription: Subscription;
constructor(private spacesService: SpacesService,
private store: Store<fromSpaces.FeatureState>
) { }
ngOnInit() {
this.spacesState = this.store.select('spaces');
this.subscription = this.spacesService.addModeActivated
.subscribe(
(addMode: boolean) => {
this.addMode = addMode;
}
);
// this.subscription = this.spacesService.spacesChanged
// .subscribe(
// (spaces: Space[]) => {
// this.spaces = spaces;
// }
// );
// this.spaces = this.spacesService.getSpaces();
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
enableAddMode() {
// this.addMode = true;
this.spacesService.addModeActivated.next(true);
}
}