【问题标题】:Angular7 - Inject Component in another ComponentAngular7 - 在另一个组件中注入组件
【发布时间】: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()
  }
}

【问题讨论】:

    标签: angular typescript angular7 angular-components


    【解决方案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

    【讨论】:

    • 是的,我知道行为主题,但我想知道如果我在另一个主题中注入组件会不会有问题?
    猜你喜欢
    • 2018-12-31
    • 2017-06-17
    • 2019-12-03
    • 2018-07-15
    • 1970-01-01
    • 2020-07-23
    • 2018-10-04
    • 2017-12-09
    • 2019-06-15
    相关资源
    最近更新 更多