通过 children 将祖先的前向引用注入到 grand-child
Injecting forward ref of ancestor through children to grand-child
问题
现在我正在使用一些组件来混淆一些更复杂的功能,使他们能够更轻松地编写代码块。
组件堆栈从代码端看起来像这样:
<smart-nav-tile-group>
<radio-checkbox-group>
<smart-nav-tile>
<radio-checkbox-wrapper>
我想要完成的是将 radio-checkbox-group
组件的前向引用注入到每个 radio-checkbox-wrapper
组件中,以便两个组件之间存在 two-way 通信。
所以在我的 radio-checkbox-wrapper
我的 constructor
函数中有以下内容:
@Inject(forwardRef(() => RadioCheckboxGroupComponent)) public inputGroup: RadioCheckboxGroupComponent
只要 RadioCheckboxGroup
组件是 RadioCheckboxWrapper
的直接 parent,这一切都很好。但是,中间的 SmartNavTile
组件会抛出以下错误:
SmartNavTileComponent.html:2 ERROR Error: StaticInjectorError(AppModule)[RadioCheckboxWrapperComponent -> RadioCheckboxGroupComponent]:
StaticInjectorError(Platform: core)[RadioCheckboxWrapperComponent -> RadioCheckboxGroupComponent]:
NullInjectorError: No provider for RadioCheckboxGroupComponent!
问题
如何在 RadioCheckboxWrapper
组件中创建对 RadioCheckboxGroup
组件的前向引用,而不管它必须在祖先树上爬多远才能找到它?
通过引用将 child 传达给 parent 并不是一个好的设计。我建议有一些服务可以帮助 parent 和 child 之间进行通信。
不相关的组件:与服务共享数据
在缺少直接连接的组件之间传递数据时,例如兄弟姐妹、祖母children 等,您应该使用共享服务。
Use case : If we create a function in any one of these components that changes the value of the message. when this function is executed the new data it’s automatically broadcast to all other components.
data.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
parent.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-parent',
template: `
{{message}}
`,
styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
}
sibling.component.ts
可以是同级或child组件
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-sibling',
template: `
{{message}}
<button (click)="newMessage()">New Message</button>
`,
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
newMessage() {
this.data.changeMessage("Hello from Sibling")
}
}
您可以使用 ViewChild() 实现,并且您可以访问模板中添加的任何组件。
<smart-nav-tile-group>
<radio-checkbox-group>
<smart-nav-tile>
<radio-checkbox-wrapper>
在radio-checkbox-group组件中,您可以使用
访问Radio Checkbox组件
@ViewChild(RadioCheckboxRrapperComponent)
radiocheckboxwrapper: RadioCheckboxRrapperComponent;
问题
现在我正在使用一些组件来混淆一些更复杂的功能,使他们能够更轻松地编写代码块。
组件堆栈从代码端看起来像这样:
<smart-nav-tile-group>
<radio-checkbox-group>
<smart-nav-tile>
<radio-checkbox-wrapper>
我想要完成的是将 radio-checkbox-group
组件的前向引用注入到每个 radio-checkbox-wrapper
组件中,以便两个组件之间存在 two-way 通信。
所以在我的 radio-checkbox-wrapper
我的 constructor
函数中有以下内容:
@Inject(forwardRef(() => RadioCheckboxGroupComponent)) public inputGroup: RadioCheckboxGroupComponent
只要 RadioCheckboxGroup
组件是 RadioCheckboxWrapper
的直接 parent,这一切都很好。但是,中间的 SmartNavTile
组件会抛出以下错误:
SmartNavTileComponent.html:2 ERROR Error: StaticInjectorError(AppModule)[RadioCheckboxWrapperComponent -> RadioCheckboxGroupComponent]:
StaticInjectorError(Platform: core)[RadioCheckboxWrapperComponent -> RadioCheckboxGroupComponent]:
NullInjectorError: No provider for RadioCheckboxGroupComponent!
问题
如何在 RadioCheckboxWrapper
组件中创建对 RadioCheckboxGroup
组件的前向引用,而不管它必须在祖先树上爬多远才能找到它?
通过引用将 child 传达给 parent 并不是一个好的设计。我建议有一些服务可以帮助 parent 和 child 之间进行通信。
不相关的组件:与服务共享数据
在缺少直接连接的组件之间传递数据时,例如兄弟姐妹、祖母children 等,您应该使用共享服务。
Use case : If we create a function in any one of these components that changes the value of the message. when this function is executed the new data it’s automatically broadcast to all other components.
data.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
parent.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-parent',
template: `
{{message}}
`,
styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
}
sibling.component.ts
可以是同级或child组件
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-sibling',
template: `
{{message}}
<button (click)="newMessage()">New Message</button>
`,
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
newMessage() {
this.data.changeMessage("Hello from Sibling")
}
}
您可以使用 ViewChild() 实现,并且您可以访问模板中添加的任何组件。
<smart-nav-tile-group>
<radio-checkbox-group>
<smart-nav-tile>
<radio-checkbox-wrapper>
在radio-checkbox-group组件中,您可以使用
访问Radio Checkbox组件@ViewChild(RadioCheckboxRrapperComponent)
radiocheckboxwrapper: RadioCheckboxRrapperComponent;