Angular 2共享数据服务无效

时间:2017-03-17 15:04:57

标签: javascript angularjs angular observable angular-services

我已经构建了一个共享数据服务,旨在保存用户的登录详细信息,然后可以用来显示标题上的用户名,但我无法让它工作。

这是我的(缩写)代码:

// Shared Service
@Injectable()
export class SharedDataService {

    // Observable string source
    private dataSource = new Subject<any>();

    // Observable string stream
    data$ = this.dataSource.asObservable();

    // Service message commands
    insertData(data: Object) {
        this.dataSource.next(data)
    }
}

...

// Login component
import { SharedDataService } from 'shared-data.service';
@Component({
    providers: [SharedDataService]
})
export class loginComponent {
    constructor(private sharedData: SharedDataService) {}

    onLoginSubmit() {
        // Login stuff
        this.authService.login(loginInfo).subscribe(data => {
             this.sharedData.insertData({'name':'TEST'});
        }
    }
}

...

// Header component
import { SharedDataService } from 'shared-data.service';
@Component({
    providers: [SharedDataService]
})
export class headerComponent implements OnInit {
    greeting: string;

    constructor(private sharedData: SharedDataService) {}

    ngOnInit() {
        this.sharedData.data$.subscribe(data => {
            console.log('onInit',data)
            this.greeting = data.name
        });
    }
}

我可以在服务insertData()方法中添加一个控制台日志,该方法更新了正在更新的模型,但是OnInit方法并没有反映出这种变化。

我编写的代码非常受到plunkr的启发,它确实有效,所以我对错误感到茫然。

在发布之前,我尝试了其他一些尝试。 This onethis one再次对演示工作,但不在我的应用中。

我正在使用Angular 2.4.8。

查看不同的教程和论坛帖子都显示了如何使共享服务正常工作的类似示例,所以我想我做错了什么。我非常擅长使用AngularJS背景来构建Angular 2,这是我真正陷入困境的第一件事。

由于

2 个答案:

答案 0 :(得分:6)

这似乎是理解Angular依赖注入的一个反复出现的问题。

基本问题在于如何配置服务提供商。

简短版本: 始终在NgModule级别配置提供程序 UNLESS 您希望为特定组件创建单独的实例。只有这样才能将它添加到您想要单独实例的组件的providers数组中。

长版: 如果您这样做,Angular的新依赖注入系统允许您拥有多个服务实例(与AngularJS相反,即只允许单例的Angular 1)。如果您在NgModule级别为服务配置提供程序,您将获得由所有组件/服务等共享的服务的单例。但是,如果您将组件配置为也具有提供程序,那么该组件(和它的所有子组件都将获得他们可以共享的不同服务实例。如果您需要,此选项允许一些强大的选项。

这是基本模型。它当然不是那么简单,但默认情况下,在NgModule级别配置提供程序的基本规则,除非您明确要求特定组件的不同实例,这将带您走远。

当你想深入了解时,check out the official Angular docs

另请注意,延迟加载也会使此基本规则复杂化,因此请再次检查文档。

修改

因此,根据您的具体情况,

@Component({
    providers: [SharedDataService]  <--- remove this line from both of your components, and add that line to your NgModule configuration instead
})

答案 1 :(得分:3)

将其添加到AppModule的@ NgModule.providers数组中:

如果将其添加到@ Component.providers数组中,那么您将SharedDataService实例的范围限制为该组件及其子组件。

换句话说,每个组件都有自己的注入器,这意味着headerComponent将创建自己的SharedDataService实例,loginComponent将创建自己的实例。