Angular7 - 在另一个组件中注入组件

Posted

技术标签:

【中文标题】Angular7 - 在另一个组件中注入组件【英文标题】:Angular7 - Inject Component in another Component 【发布时间】:2020-01-10 09:30:53 【问题描述】:

在另一个组件中注入组件以访问注入组件中的功能或属性是否正确? 注意:这些组件都不是另一个组件的子组件

import  UsersComponent  from './../users/users.component';

@Component(
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
)
export class HomeComponent implements OnInit 

  constructor(users:UsersComponent)
    users.getAllUsers()
  

【问题讨论】:

【参考方案1】:

您实际上不能这样做。在 Angular 中,我们认为一切都是明智的。如果多个组件使用任何方法或属性,您可以遵循以下方法。由于您的组件与子父级无关。您可以遵循 3 和 4 方法。

1. Parent to Child 和 Child to Parent: 通过@Input 和@Output 共享数据

这是在组件之间共享数据最常用的方式。它使用 @Input() 装饰器。您还可以使用 @Output() 装饰器将事件传递给父级。

parent.component.ts:

@Component(
  selector: 'app-parent',
  template: `
    <p> message </p>
    <app-child [input]="parentData" (output)="childMsg($event)"></app-child>`
)
export class ParentComponent
  message: string;
  parentData = "message from parent"
  childMsg(event) 
    this.message = event;
  

child.component.ts:

@Component(
  selector: 'app-child',
  template: `
    <p> input </p>
    <button (click)="submit()">Submit</button>
  `
)
export class ChildComponent 

  @Input() input: string;
  @Output() output = new EventEmitter<string>();
  message: string = "Hello World!"
  submit() 
    this.output.emit(this.message)
  

2。子到父: 通过 ViewChild 共享数据

@ViewChild 装饰器允许将一个组件注入到另一个组件中,从而使父组件能够访问其属性和方法。

parent.component.ts

@Component(
  selector: 'app-parent',
  template: `
    Message:  childData 
    <app-child></app-child>
  `,
  styleUrls: ['./parent.component.css']
)
export class ParentComponent implements AfterViewInit 

  @ViewChild(ChildComponent) child;    

  childData: string;

  ngAfterViewInit() 
    this.childData = this.child.message
  

child.component.ts:

@Component(
  selector: 'app-child',
)
export class ChildComponent 

  childData = 'Hola Mundo!';


注意:我们使用 AfterViewInit lifeCycle 是因为在初始化视图之前子级不可用。

3.使用服务的不相关组件: 使用服务和行为主题在不相关组件之间共享数据

common.service.ts:

@Injectable()
export class CommonService 
  private data = new BehaviorSubject('default data');
  data$ = this.data.asObservable();

  changeData(data: string) 
    this.data.next(data)
  

component-one.component.ts:

@Component(
  selector: 'app-component-one',
  template: `<p>data</p>`
)
export class ComponentOneComponent implements OnInit 

  data: string;

  constructor(private service: CommonService)  

  ngOnInit() 
    this.service.data$.subscribe(res => this.data = res)
  


component-two.component.ts:

@Component(
  selector: 'app-component-two',
  template: `
    <p>data</p>
    <button (click)="newData()">Next Data</button>`
)
export class ComponentTwoComponent implements OnInit 

  data: string;

  constructor(private service: CommonService)  

  ngOnInit() 
    this.service.data$.subscribe(res => this.data = res)
  
  newData() 
    this.service.data.next('Changed Data');
  

4.状态管理: 使用 NgRx 在不相关的组件之间共享数据 你可以使用像 NgRx 这样的存储来管理你将存储你的财产的状态,然后在任何地方使用。 Example我学习ngrx的时候就是按照这个例子来的。

【讨论】:

在最后一个例子中 (component-two.component.ts) 我想你的意思是:export class ComponentTwoComponent 是的,你是对的,我只是复制了componentOne并尝试编辑并忘记编辑类名。 感谢您的典型回答,对我很有帮助。【参考方案2】:

不,您不能将一个组件注入另一个组件。您应该为此创建一个服务。

您可以使用Behaviour Subject 在两个不相关的组件之间进行通信。

看到这个tutorial

【讨论】:

是的,我知道行为主题,但我想知道如果我在另一个主题中注入组件会不会有问题?

以上是关于Angular7 - 在另一个组件中注入组件的主要内容,如果未能解决你的问题,请参考以下文章

我的 Angular 7 组件已连接到数据源,但未显示数据

Angular 7 - 向动态创建的组件添加拖放行为

如何在服务中初始化响应式表单而不是注入到组件中

如何在Angular7中使用另一个组件中的变量

如何在两个组件之间使用Angular7(角度材料)拖放

Angular7 - [ngModel] 不会在组件中更新,当两次输入相同的值时