如何在Angular 2中在组件之间共享数据?

30 浏览
0 Comments

如何在Angular 2中在组件之间共享数据?

在Angular 1.x.x中,你只需要请求相同的服务,就会得到相同的实例,从而可以在服务中共享数据。

现在在Angular 2中,我有一个组件引用了我的服务。我可以读取和修改服务中的数据,这是好的。但是当我尝试在另一个组件中注入相同的服务时,似乎会得到一个新的实例。

我做错了什么?是模式本身有问题(使用服务来共享数据),还是我需要将服务标记为单例(在应用程序的一个实例中)或其他什么?

我使用2.0.0-alpha.27/版本。

我通过appInjector(现在是providers)在@Component注解中注入一个服务,然后在构造函数中保存一个引用。它在组件内部可以正常工作,但在不同的组件之间却不共享相同的服务实例,这与我之前的想法不同。

更新:从Angular 2.0.0开始,我们现在有了@ngModule,你可以在该@ngModule的providers属性下定义服务。这将确保每个组件、服务等在该模块中使用相同的服务实例。

https://angular.io/docs/ts/latest/guide/ngmodule.html#providers

更新:Angular和FE开发已经有了很多变化。如@noririco所提到的,你还可以使用像NgRx这样的状态管理系统:

https://ngrx.io/

0
0 Comments

问题的原因是在组件中添加了providers属性,导致每次注入服务时都会创建一个新的实例,而不是使用单例模式。解决方法是只在模块中添加服务的providers属性,而在组件中不添加。

在Angular 2中,如何在组件之间共享数据?

问题的原因是在组件中添加了providers属性,这导致每次注入服务时都会创建一个新的实例,而不是使用单例模式。解决方法是只在模块中添加服务的providers属性,而在组件中不添加。

具体来说,当我们在组件中添加providers属性时,如下所示:

({
    selector: 'my-selector',
    providers: [MyService],
    template: `
stuff
` })

这会导致每次注入MyService时都会创建一个新的实例。为了解决这个问题,我们只需要在应用的模块中添加MyService的providers属性,而在组件中不添加,如下所示:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyComponent } from './my-component';
import { MyService } from './my-service';
@NgModule({
    imports: [BrowserModule],
    declarations: [MyComponent],
    providers: [MyService], // 在模块中添加服务的providers属性
    bootstrap: [MyComponent]
})
export class AppModule { }

这样,我们就可以在组件之间共享同一个MyService实例,而不是每次都创建一个新的实例。

需要注意的是,这并不意味着MyService是一个真正的单例,而是同一个实例在组件之间传递。如果需要一个新的实例,仍然可以通过注入MyService来实现。

0
0 Comments

在Angular 2中如何在组件之间共享数据?

在Angular 2中,有多种方法可以在组件之间共享数据。其中一种方法是使用服务单例。另一种方法是使用数据/事件绑定。

以下是两种方法的示例代码:

class BazService{
  n: number = 0;
  inc(){
    this.n++;
  }
}
@Component({
  selector: 'foo',
  template: ``
})
class FooComponent{
  constructor(foobaz: BazService){
    this.foobaz = foobaz;
  }
}
@Component({
  selector: 'bar',
  properties: ['prop'],
  template: ``
})
class BarComponent{
  constructor(barbaz: BazService){
    this.barbaz = barbaz;
  }
}
@Component({
    selector: 'app',
    viewInjector: [BazService],
  template: `
    
    
  `,
  directives: [FooComponent, BarComponent]
})
class AppComponent{}
bootstrap(AppComponent);

通过使用服务单例或数据/事件绑定,我们可以在Angular 2中实现组件之间的数据共享。

注意:在Angular 2的较新版本中,`appInjector`已被移除,应该使用`viewInjector`代替。

0
0 Comments

因为在Angular 2中,组件之间不能直接共享数据,需要使用输入和输出装饰器来实现。下面是一个使用输入和输出装饰器的基本示例:

首先,我们需要在子组件中定义输入和输出的属性。子组件中的输入属性用于接收父组件传递过来的数据,输出属性用于向父组件传递数据。在这个例子中,子组件的输入属性是items,输出属性是onItemSelected。代码如下:

@Component({
  selector: 'sub-component',
  inputs: ['items'],
  outputs: ['onItemSelected'],
  template: `
    
{{ item }}
` }) class SubComponent { onItemSelected: EventEmitter; items: string[]; constructor() { this.onItemSelected = new EventEmitter(); } select(i) { this.onItemSelected.emit(this.items[i]); } }

在父组件中,我们需要将子组件作为指令引入,并在模板中使用子组件,并传递数据给子组件的输入属性,并监听子组件的输出属性。在这个例子中,父组件的模板中使用了子组件,通过属性绑定将父组件的items属性传递给子组件的items属性,并监听子组件的onItemSelected输出属性,当子组件中的按钮被点击时,触发itemSelected方法。代码如下:

@Component({
  selector: 'app',
  directives: [SubComponent],
  template: `
    
` }) class App { items: string[]; constructor() { this.items = ['item1', 'item2', 'item3']; } itemSelected(item: string): void { console.log('Selected item:', item); } }

最后,我们需要使用bootstrap函数来启动应用程序,并将父组件作为参数传递给它。代码如下:

bootstrap(App);

在这个例子中,当子组件中的按钮被点击时,会触发itemSelected方法,将选中的item传递给父组件,并在控制台上输出选中的item。

需要注意的是,在模板中使用了Angular内置的ngFor指令来循环渲染子组件中的每个item。在这个例子中,我们不需要手动导入ngFor指令,因为它已经在Angular 2的common模块中,会自动被引入。

0