2017-02-16 80 views
1

我正在開發一個Angular項目,其中我懶惰地加載功能模塊,並且在我的某個模塊中遇到了一個奇怪的錯誤。角度服務不在模塊中共享

我使用NgModule的「providers」屬性在模塊級別提供服務。我期望(並且能夠以前用這種方式使用服務)服務將在模塊中的所有組件之間共享。但是,當我將服務注入到模塊中的組件中時,它們將作爲單獨的實例注入。

在我的項目中,我有兩個組件,我已經觀察到這個,一個列表組件和一個編輯組件。我在我的服務中設置一個值,當我在列表組件中嘗試與編輯組件共享時,但是當我從列表組件到編輯組件時,服務被重新實例化,並且相同因爲當我從編輯組件到列表組件。

有誰知道可能會導致什麼呢?我以前可以在模塊中使用共享服務,所以我不確定我在做什麼錯誤。

下面是組件,模塊的代碼,並且服務:

列表組件:

import { Component, OnInit } from '@angular/core'; 
import { Observable } from 'rxjs'; 
import { Project } from '../../../shared/models/project'; 
import { ProjectService } from '../../project.service'; 
import { Router } from '@angular/router'; 

@Component({ 
    selector: 'app-project-list-main', 
    templateUrl: './project-list-main.component.html', 
    styleUrls: ['./project-list-main.component.scss'] 
}) 
export class ProjectListMainComponent implements OnInit { 
    private projects$: Observable<Project[]>; 
    private selectedItem: Project; 

    onSelectedItem(event){ 
    this.selectedItem = event; 
    } 

    editProject(){ 
    this.projectService.setEditProject(this.selectedItem); 
    this.router.navigateByUrl('/pages/projects/edit'); 
    } 

    deleteProject(){ 
    this.projectService.delete(this.selectedItem.id); 
    } 

    constructor(private router: Router, private projectService: ProjectService) { } 

    ngOnInit() { 
    this.projects$ = this.projectService.projects; 
    } 
} 

編輯組件:

import { Component, OnInit, Input } from '@angular/core'; 
import { Validators, FormGroup, FormArray, FormBuilder } from '@angular/forms'; 
import { ProjectService } from '../../project.service'; 
import { Project } from '../../../shared/models/project'; 
import { Router } from '@angular/router'; 

@Component({ 
    selector: 'app-project-edit-main', 
    templateUrl: './project-edit-main.component.html', 
    styleUrls: ['./project-edit-main.component.scss'] 
}) 
export class ProjectEditMainComponent implements OnInit { 
    public projectForm: FormGroup; 
    @Input() editProject: Project; 

    constructor(private fb: FormBuilder, private router: Router, private projectService: ProjectService) { } 

    saveProject(event){ 
    this.projectService.add(event); 
    this.router.navigateByUrl('/pages/projects'); 
    } 

    ngOnInit() { 
    this.projectForm = this.fb.group({ 
     name: ['',Validators.required], 
     description: [''], 
     type: ['', Validators.required] 
    }); 
    this.projectService.editProject.subscribe(editProject => { 
     if(editProject) 
     this.projectForm.patchValue(editProject); 
    }); 
    } 
} 

服務:

import { Injectable } from "@angular/core"; 
import { BehaviorSubject } from "rxjs/BehaviorSubject"; 
import { Observable } from "rxjs/Observable"; 
import { Project } from "../shared/models/project"; 
import { DataService } from "../shared/services/data.service"; 
import { Router } from "@angular/router"; 
import { AlertService } from "../shared/alert/alert.service"; 

@Injectable() 
export class ProjectService { 
    private _projects: BehaviorSubject<Project[]> = new BehaviorSubject([]); 
    projects: Observable<Project[]> = this._projects.asObservable(); 
    private _editProject: BehaviorSubject<Project> = new BehaviorSubject(null); 
    editProject: Observable<Project> = this._editProject.asObservable(); 

    editing: boolean = false; 

    private dataStore: { 
     projects: Project[] 
    }; 

    loadall() { 
     this.dataService.GetAll("projects") 
      .subscribe(projects => { 
       this.dataStore.projects = projects; 
       this._projects.next(Object.assign({}, this.dataStore).projects); 
      }, error => { 
       console.log(error); 
       this.alertService.error('Error', 'Encountered error while loading Projects'); 
      }); 
    } 

    setEditProject(editProject: Project){ 
     this._editProject.next(editProject); 
     this.editing = true; 
    } 

    add(project: Project) { 
     this.dataService.Add('projects', project).subscribe(project => { 
      this.dataStore.projects.push(project); 
      this._projects.next(Object.assign({}, this.dataStore).projects); 
     }, error => { 
      console.log(error); 
      this.alertService.error('Error', 'Encountered error while adding Project'); 
     }); 
    } 

    update(project: Project) { 
     let editId = this._editProject.getValue().id; 
     project.id = editId; 
     this.dataService.Update('projects', editId, project).subscribe(() => { 
      this.dataStore.projects.forEach((p, i) => { 
       if (p.id === project.id) { this.dataStore.projects[i] = project; } 
      }); 
      this._projects.next(Object.assign({}, this.dataStore).projects); 
     }, error => { 
      console.log(error); 
      this.alertService.error('Error', 'Encountered error while updating Project'); 
     }); 
     this.editing = false; 
     this._editProject.next(null); 
    } 

    delete(id: number) { 
     this.dataService.Delete('projects', id).subscribe(response => { 
      this.dataStore.projects.forEach((p, i) => { 
       if (p.id === id) { this.dataStore.projects.splice(i, 1); } 
      }); 
      this._projects.next(Object.assign({}, this.dataStore).projects); 
     }, error => { 
      console.log(error); 
      this.alertService.error('Error', 'Encountered error while deleting Project'); 
     }); 
    } 



    constructor(private router: Router, private dataService: DataService, private alertService: AlertService) { 
     this.dataStore = { projects: [] }; 
     this.loadall(); 
    } 
} 

模塊:

import { NgModule } from '@angular/core'; 
import { CommonModule } from '@angular/common'; 
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 
import { ProjectRoutingModule } from './project-routing.module'; 

// Primeng module imports 
import { CalendarModule, DataTableModule, DialogModule, ConfirmDialogModule, ConfirmationService, PanelModule, DropdownModule } from 'primeng/primeng'; 

// Dumb components 
import { ProjectEditComponent } from './edit/project-edit.component'; 
import { ProjectListComponent } from './list/project-list.component'; 
import { ProjectCardComponent } from './card/project-card.component'; 
import { ProjectDetailComponent } from './detail/project-detail.component'; 
import { ProjectDeleteOptionsComponent } from './delete/project-delete-options.component'; 

// Containers 
import { ProjectEditMainComponent } from './containers/project-edit-main/project-edit-main.component'; 
import { ProjectListMainComponent } from './containers/project-list-main/project-list-main.component'; 
import { ProjectComponent } from './project.component'; 

// Services 
import { ProjectService } from './project.service'; 

@NgModule({ 
    imports: [ 
    CommonModule, 
    ProjectRoutingModule, 
    FormsModule, 
    ReactiveFormsModule, 
    DataTableModule, 
    DropdownModule, 
    PanelModule 
    ], 
    declarations: [ 
    ProjectCardComponent, 
    ProjectDetailComponent, 
    ProjectEditComponent, 
    ProjectListComponent, 
    ProjectDeleteOptionsComponent, 
    ProjectComponent, 
    ProjectEditMainComponent, 
    ProjectListMainComponent 
    ], 
    providers: [ProjectService] 
}) 
export class ProjectModule { } 
+0

的一段代碼將是有益的:) –

+0

一些代碼 – Deej

+0

更新這可以幫助你:https://angular-2-training-book.rangle.io/handout/modules/shared-di- tree.html – VuuRWerK

回答

0

你只需要導入另一個模塊(A),如果你需要以下條件:從導入模塊

  • 指令,組件或管道(A)

知道這,如果你導入一個模塊(A),也提供了一個服務,並且你最終得到了一個新的服務實例,那麼這個模塊(A)可能被錯誤地設置了,因爲你期望服務是一個應用程序 - 寬的單身人士。

標準模塊註冊可用於底層組件的服務。共享模塊(如果它也希望共享服務)將服務註冊到應用程序的根目錄中,可以使用.forRoot()方法完成此操作。

import { NgModule, ModuleWithProviders } from '@angular/core'; 
import { CommonModule } from '@angular/common'; 

import { authObjService } from './service/authObj'; 
import { loginGuard } from './service/loginGuard'; 
import {loginButton} from './directive/login-button/login-button' 
import {logoutButton} from './directive/logout-button/logout-button' 


@NgModule({ 
    declarations: [loginButton, logoutButton], 
    imports: [CommonModule], 
    exports: [loginButton, logoutButton], 
}) 

export class authenticationModule { 
    static forRoot(): ModuleWithProviders { 
     return { 
      ngModule: authenticationModule, 
      providers: [authObjService, loginGuard] 
     } 
    } 
}