Angular 4 Master/Detail 组件之间的服务通信 children
Angular 4 Master/Detail service communication between children components
我在 parent 组件中有 2 个 child 组件,childA 和 childB 充当 master/detail。
我正在使用从 webAPI 获取数据的共享服务,这些 children 使用此共享服务获取数据。
api/messages - 获取全部 messages/Master
api/messages/1 - 收到 1 条带有 id/Detail
的消息
Child A 是 master 使用服务在视图中显示消息列表。 api/messages returns所有消息,每条消息都有一个id。
现在,当我在消息的主列表中单击时,我能够获取消息的 ID 并将其保存到主组件中的变量中。
现在的问题是当在主组件中单击消息时如何在详细信息组件中显示消息详细信息。我尝试将 ID 传递给服务,但它不起作用
共享消息服务:
export class MessageService {
constructor(private http: HttpClient) { }
getMessages(): Observable<any> {
return this.http.get('/api/messages').map(data => data)
}
getMessageById(): Observable<any> {
return this.http.get('/api/messages/3' ).map(data => data)
//id 3 应该来自主组件并传递该 id。
}
}
主组件:显示列表中的消息列表
emails: any[];
constructor(private messageService: MessageService) { }
ngOnInit() {
this.messageService.getMessages().subscribe(data => this.emails =
data.messages);
}
}
详细组件
message;
constructor(private messageService: MessageService) {
}
ngOnInit() {
this.messageService.getMessageById().subscribe(data => this.message =
data);
}
}
您可以在您的详细信息组件中有一个 @Input
属性,并且可以根据您在主组件中选择的内容进行更改。
类似于下面的内容,
<detail [id]='<id coming from list>'></detail>
设置ID时调用API,
private _id: string = "";
@Input()
get Id(): string {
return this._id;
}
set Id(id: string) {
if (this._id !== id) {
this._id = id;
// call API
}
}
现在您可以将主列表中的 ID 作为主列表组件中的事件传递。
一个优雅的解决方案是使用主题模式(这是一种可观察的类型)在组件和服务之间进行通信。
主题模式示例:
处理消息的服务:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: string) {
this.subject.next({ text: message });
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
接收消息的应用程序组件:
import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { MessageService } from './_services/index';
@Component({
moduleId: module.id,
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent implements OnDestroy {
message: any;
subscription: Subscription;
constructor(private messageService: MessageService) {
// subscribe to home component messages
this.subscription = this.messageService.getMessage().subscribe(message => { this.message = message; });
}
ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}
}
更高级的模式是在您的应用程序中实施 Redux。
Redux 的关键思想是:
- 您应用程序的所有数据都在一个称为状态的数据结构中 - 它保存在商店中
- 您的应用从该商店读取状态
- 这家商店永远不会直接变异
- 用户交互(和其他代码)触发描述发生的事情的动作
- 通过将旧状态与称为 reducer 的函数结合起来创建新状态。
您可以在这篇详细的 Redux Reference with examples
中阅读有关 Redux 的更多信息
我在 parent 组件中有 2 个 child 组件,childA 和 childB 充当 master/detail。
我正在使用从 webAPI 获取数据的共享服务,这些 children 使用此共享服务获取数据。
api/messages - 获取全部 messages/Master
api/messages/1 - 收到 1 条带有 id/Detail
的消息Child A 是 master 使用服务在视图中显示消息列表。 api/messages returns所有消息,每条消息都有一个id。
现在,当我在消息的主列表中单击时,我能够获取消息的 ID 并将其保存到主组件中的变量中。 现在的问题是当在主组件中单击消息时如何在详细信息组件中显示消息详细信息。我尝试将 ID 传递给服务,但它不起作用
共享消息服务:
export class MessageService {
constructor(private http: HttpClient) { }
getMessages(): Observable<any> {
return this.http.get('/api/messages').map(data => data)
}
getMessageById(): Observable<any> {
return this.http.get('/api/messages/3' ).map(data => data)
//id 3 应该来自主组件并传递该 id。
}
}
主组件:显示列表中的消息列表
emails: any[];
constructor(private messageService: MessageService) { }
ngOnInit() {
this.messageService.getMessages().subscribe(data => this.emails =
data.messages);
}
}
详细组件
message;
constructor(private messageService: MessageService) {
}
ngOnInit() {
this.messageService.getMessageById().subscribe(data => this.message =
data);
}
}
您可以在您的详细信息组件中有一个 @Input
属性,并且可以根据您在主组件中选择的内容进行更改。
类似于下面的内容,
<detail [id]='<id coming from list>'></detail>
设置ID时调用API,
private _id: string = "";
@Input()
get Id(): string {
return this._id;
}
set Id(id: string) {
if (this._id !== id) {
this._id = id;
// call API
}
}
现在您可以将主列表中的 ID 作为主列表组件中的事件传递。
一个优雅的解决方案是使用主题模式(这是一种可观察的类型)在组件和服务之间进行通信。
主题模式示例:
处理消息的服务:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: string) {
this.subject.next({ text: message });
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
接收消息的应用程序组件:
import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { MessageService } from './_services/index';
@Component({
moduleId: module.id,
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent implements OnDestroy {
message: any;
subscription: Subscription;
constructor(private messageService: MessageService) {
// subscribe to home component messages
this.subscription = this.messageService.getMessage().subscribe(message => { this.message = message; });
}
ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}
}
更高级的模式是在您的应用程序中实施 Redux。 Redux 的关键思想是:
- 您应用程序的所有数据都在一个称为状态的数据结构中 - 它保存在商店中
- 您的应用从该商店读取状态
- 这家商店永远不会直接变异
- 用户交互(和其他代码)触发描述发生的事情的动作
- 通过将旧状态与称为 reducer 的函数结合起来创建新状态。
您可以在这篇详细的 Redux Reference with examples
中阅读有关 Redux 的更多信息