Angular 2如何从组件向服务发送数据

17

我的目标是从Angular组件发送数据到服务中并使用服务方法对其进行处理。例如:

export class SomeComponent {
    public data: Array<any> = MyData;
    public constructor(private myService: MyService) {
      this.myService.data = this.data;
    }
}

和服务:

@Injectable()
export class TablePageService {
    public data: Array<any>;
    constructor() {
        console.log(this.data);
        // undefined
    }
}

获取数据未定义。如何使其正常工作?


2
当你将服务注入到组件中时,服务构造函数已经运行 - 因为你没有初始化它,所以此时的“data”是未定义的。 - Joe Clay
在你调用对象的方法之前,它必须被构造。因此,你的构造函数被调用并且数据是未定义的。然后在之后你访问成员并修改变量,但构造函数已经被调用了。 - Akkusativobjekt
我该如何修复这个问题? - IntoTheDeep
1
我建议您使用方法在组件和服务之间进行通信。还要使用订阅来确保在数据可用时接收数据。在此处查看文档,非常有用:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service - SrAxi
这是 TypeScript 而不是 JavaScript,对吗? - Akkusativobjekt
是的,TypeScript。我改正了。 - IntoTheDeep
2个回答

32

服务和组件之间的一个交互示例可能是:

服务:

@Injectable()
export class MyService {
    myMethod$: Observable<any>;
    private myMethodSubject = new Subject<any>();

    constructor() {
        this.myMethod$ = this.myMethodSubject.asObservable();
    }

    myMethod(data) {
        console.log(data); // I have data! Let's return it so subscribers can use it!
        // we can do stuff with data if we want
        this.myMethodSubject.next(data);
    }
}

组件1(发送者):

export class SomeComponent {
    public data: Array<any> = MyData;

    public constructor(private myService: MyService) {
        this.myService.myMethod(this.data);
    }
}

组件2(接收器):

export class SomeComponent2 {
    public data: Array<any> = MyData;

    public constructor(private myService: MyService) {
        this.myService.myMethod$.subscribe((data) => {
                this.data = data; // And he have data here too!
            }
        );
    }
}

解释:

MyService 管理着 data。如果您想,仍然可以对 data 做一些事情,但最好让 Component2 来处理。

基本上,MyServiceComponent1 接收 data,并将其发送给订阅了方法 myMethod() 的任何人。

Component1data 发送到 MyService,这就是他所做的全部。 Component2 订阅了 myMethod(),因此每次调用 myMethod() 时,Component2 都会侦听并获取 myMethod() 返回的任何内容。


组件2中的MyData来自哪里? - IntoTheDeep
2
我刚从你的代码中拿到了这个:public data: Array<any> = MyData;。它也可以声明为public data = {};,具体取决于你正在处理的数据类型。我只是想让它与你的示例保持接近,以便你更容易理解。 - SrAxi
1
在同一个方法中传递第二个参数。https://www.w3schools.com/js/js_function_parameters.asp - SrAxi
嗨,我发现你的解决方案非常准确,但是在接收器组件中我遇到了一些问题,所以让我问你一个问题:从subscribe返回的数据必须是一个偶数对象的数组吗? - Nad G
1
@SrAxi,Snap,我还以为问题是数据类型呢xD。好的,知道它可以是任何类型就好了。谢谢你的回答! - Nad G
显示剩余3条评论

0

@SrAxi在回答中的接收器组件存在一个小问题,无法订阅服务数据。建议考虑使用BehaviorSubject替代Subject。这对我很有效!

private myMethodSubject = new BehaviorSubject<any>("");

1
BehaviorSubject 只是 Subject 的一种专门化,它从数据流中获取最新的值。问题可能不在于你代码中的 Subject 类型,而更可能与你订阅时机有关。 - SrAxi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接