Angular 2单例服务没有作为单例执行。

16 浏览
0 Comments

Angular 2单例服务没有作为单例执行。

我有一个名为TargetService的服务,我将其注入到其他组件中。这个TargetService有一个叫做Targets的属性,它是一个Target对象的集合。

我的问题是,我希望这个集合在路由到另一个视图后仍然存在。我的路由工作正常,但一旦路由改变,服务就会丢失任何变量的内容,实际上,它正在重新初始化服务。我的理解是,这些注入的服务应该是可以传递的单例?

在下面的例子中,在TargetIndex上,我点击一个按钮来填充服务上的Targets[]对象(this.targetService.targets = ts;)。这个工作正常,然后我路由到TargetShow页面,然后返回到这个索引,现在这个Targets[]属性是空的,而我希望它包含我已经填充的内容。

我在这里缺少了什么?

App.Module

const routes: Routes = [
  { path: '', redirectTo: 'targets', pathMatch: 'full'},
  { path: 'targets', component: TargetIndexComponent },
  { path: 'targets/:id', component: TargetShowComponent }
]
@NgModule({
  declarations: [
    AppComponent,
    TargetComponent,
    TargetIndexComponent,
    TargetShowComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    HttpModule,
    RouterModule.forRoot(routes)
  ],
  providers: [TargetService],
  bootstrap: [AppComponent]
})
export class AppModule { }

TargetService

@Injectable()
export class TargetService {
  public targets: Target[];
  constructor(private http: Http) {}
  getTargets(hostname: String): Observable {
    return this.http.request(`url`).map(this.extractData);
  }
  private extractData(res: Response) {
    let body = res.json();
    return body || [];
  }
}

TargetIndex

@Component({
  selector: 'app-targets',
  templateUrl: './target-index.component.html',
  providers: [TargetService]
})
export class TargetIndexComponent {
  loading = false;
  constructor(private http: Http, private targetService: TargetService) {}
  loadTargets(hostname: HTMLInputElement) {
    this.loading = true;
    this.targetService.getTargets(hostname.value)
    .subscribe((ts: Target[]) => {
      this.targetService.targets = ts;
      this.loading = false;
    })
  } 
}

TargetShow

@Component({
  selector: 'app-target-show',
  templateUrl: './target-show.component.html'
  providers: [TargetService]
})
export class TargetShowComponent {
  id: string
  constructor(private route: ActivatedRoute, private targetService: TargetService) {
    route.params.subscribe(params => { this.id = params['id']; })
  }
}

0
0 Comments

Angular 2单例服务不作为单例服务的原因是因为在组件的providers中添加了TargetService,而在模块的providers中已经添加了它。当你将这个服务添加到组件的providers中时,依赖注入会创建它的新实例。

解决方法是从组件的providers中移除TargetService,因为你已经在模块的providers中添加了它。

这是来自https://angular.io/docs/ts/latest/guide/dependency-injection.html的引用:

何时使用NgModule和应用程序组件?一方面,NgModule中的提供者在根注入器中注册。这意味着在NgModule中注册的每个提供者都可以在整个应用程序中访问。

另一方面,注册在应用程序组件中的提供者只适用于该组件及其所有子组件。

谢谢你!当我这样做时,Atom会抱怨一个缺少的属性,但它编译得很好,按预期工作。我认为Atom TypeScript只是有点有问题。

0