当前位置: 首页 > 知识库问答 >
问题:

如何在angular2中调用另一个组件函数

金令秋
2023-03-14

我有两个组件,如下所示,我想从另一个组件调用一个函数。这两个组件都包含在第三个父组件 using 指令中。

构成部分1:

@component(
    selector:'com1'
)
export class com1{
    function1(){...}
}

@component(
    selector:'com2'
)
export class com2{
    function2(){...
        // i want to call function 1 from com1 here
    }
}

我尝试过使用@input@output但我不知道如何使用它以及如何调用该函数,任何人都可以帮忙吗?

共有3个答案

冯皓
2023-03-14
  ngOnInit() {}

  public testCall(){
    alert("I am here..");    
  }
import { oneComponent } from '../one.component';


@Component({
  providers:[oneComponent ],
  selector: 'app-two',
  templateUrl: ...
}


constructor(private comp: oneComponent ) { }

public callMe(): void {
    this.comp.testCall();
  }

组件两个 html 文件

<button (click)="callMe()">click</button>
艾谦
2023-03-14

如果 com1 和 com2 是兄弟姐妹,您可以使用

@component({
  selector:'com1',
})
export class com1{
  function1(){...}
}

com2使用< code>EventEmitter发出一个事件

@component({
  selector:'com2',
  template: `<button (click)="function2()">click</button>`
)
export class com2{
  @Output() myEvent = new EventEmitter();
  function2(){...
    this.myEvent.emit(null)
  }
}

这里,父组件添加了一个事件绑定来侦听< code>myEvent事件,然后在此类事件发生时调用< code>com1.function1()。< code>#com1是一个模板变量,允许从模板中的其他地方引用该元素。我们用它来使< code>function1()成为< code>com2的< code>myEvent的事件处理程序:

@component({
  selector:'parent',
  template: `<com1 #com1></com1><com2 (myEvent)="com1.function1()"></com2>`
)
export class com2{
}

关于组件间通信的其他选项,请参见组件交互

季小云
2023-03-14

首先,您需要了解组件之间的关系。然后,您可以选择正确的通信方式。我将尝试解释我在实践中知道并使用的所有方法,以进行组件之间的通信。

组件之间可以有什么样的关系?

1. 家长

通过输入共享数据

parent.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'parent-component',
  template: `
    <child-component [childProperty]="parentProperty"></child-component>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent{
  parentProperty = "I come from parent"
  constructor() { }
}

child.component.ts

import { Component, Input } from '@angular/core';

@Component({
  selector: 'child-component',
  template: `
      Hi {{ childProperty }}
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  @Input() childProperty: string;

  constructor() { }

}

这是一个非常简单的方法。它很容易使用。我们还可以使用ngOnChanges捕捉子组件中的数据变化。

但不要忘记,如果我们使用一个对象作为数据并更改该对象的参数,对它的引用将不会更改。因此,如果我们想在子组件中接收修改后的对象,它必须是不可变的。

通过ViewChild共享数据

ViewChild允许将一个组件注入到另一个组件中,使父组件可以访问其属性和功能。但是,有一点需要注意,在视图初始化之前,< code>child是不可用的。这意味着我们需要实现AfterViewInit生命周期钩子来接收来自孩子的数据。

parent.component.ts

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from "../child/child.component";

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

  @ViewChild(ChildComponent) child;

  constructor() { }

  message:string;

  ngAfterViewInit() {
    this.message = this.child.message
  }
}

child.component.ts

import { Component} from '@angular/core';

@Component({
  selector: 'child-component',
  template: `
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  message = 'Hello!';

  constructor() { }

}

通过 Output() 和 EventEmitter 共享数据

共享数据的另一种方法是从子级发出数据,该数据可以由父级列出。当您想要共享在按钮单击、表单条目和其他用户事件等事件上发生的数据更改时,此方法是理想的选择。

parent.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'parent-component',
  template: `
    Message: {{message}}
    <child-component (messageEvent)="receiveMessage($event)"></child-component>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {

  constructor() { }

  message:string;

  receiveMessage($event) {
    this.message = $event
  }
}

child.component.ts

import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'child-component',
  template: `
      <button (click)="sendMessage()">Send Message</button>
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  message: string = "Hello!"

  @Output() messageEvent = new EventEmitter<string>();

  constructor() { }

  sendMessage() {
    this.messageEvent.emit(this.message)
  }
}

3. 兄弟姐妹

孩子

parent.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'parent-component',
  template: `
    Message: {{message}}
    <child-one-component (messageEvent)="receiveMessage($event)"></child1-component>
    <child-two-component [childMessage]="message"></child2-component>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {

  constructor() { }

  message: string;

  receiveMessage($event) {
    this.message = $event
  }
}

child-one .组件. ts

import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'child-one-component',
  template: `
      <button (click)="sendMessage()">Send Message</button>
  `,
  styleUrls: ['./child-one.component.css']
})
export class ChildOneComponent {

  message: string = "Hello!"

  @Output() messageEvent = new EventEmitter<string>();

  constructor() { }

  sendMessage() {
    this.messageEvent.emit(this.message)
  }
}

child-two.ts

import { Component, Input } from '@angular/core';

@Component({
  selector: 'child-two-component',
  template: `
       {{ message }}
  `,
  styleUrls: ['./child-two.component.css']
})
export class ChildTwoComponent {

  @Input() childMessage: string;

  constructor() { }

}

4.不相关组件

我下面描述的所有方法都可以用于组件之间关系的所有上述选项。但各有利弊。

与服务共享数据

当在缺少直接连接的组件之间传递数据时,比如兄弟、孙等,应该使用共享服务。当您有应该总是同步的数据时,我发现RxJS BehaviorSubject在这种情况下非常有用。

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)
  }

}

第一.ts组件

import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";

@Component({
  selector: 'first-componennt',
  template: `
    {{message}}
  `,
  styleUrls: ['./first.component.css']
})
export class FirstComponent implements OnInit {

  message:string;

  constructor(private data: DataService) {
      // The approach in Angular 6 is to declare in constructor
      this.data.currentMessage.subscribe(message => this.message = message);
  }

  ngOnInit() {
    this.data.currentMessage.subscribe(message => this.message = message)
  }

}

第二个组件是.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";

@Component({
  selector: 'second-component',
  template: `
    {{message}}
    <button (click)="newMessage()">New Message</button>
  `,
  styleUrls: ['./second.component.css']
})
export class SecondComponent implements OnInit {

  message:string;

  constructor(private data: DataService) { }

  ngOnInit() {
    this.data.currentMessage.subscribe(message => this.message = message)
  }

  newMessage() {
    this.data.changeMessage("Hello from Second Component")
  }

}

与路径共享数据

有时,您不仅需要在组件之间传递简单的数据,还需要保存页面的某些状态。例如,我们希望在在线市场中保存一些过滤器,然后复制此链接并发送给朋友。我们希望它以与我们相同的状态打开页面。第一种可能也是最快的方法是使用查询参数。

查询参数看起来更像< code>/people?id=其中< code>id可以等于任何值,并且您可以拥有任意多个参数。查询参数将由&字符分隔。

import {Component} from "@angular/core";
import {Router, NavigationExtras} from "@angular/router";

@Component({
    selector: "page1",
  template: `
    <button (click)="onTap()">Navigate to page2</button>
  `,
})
export class Page1Component {

    public constructor(private router: Router) { }

    public onTap() {
        let navigationExtras: NavigationExtras = {
            queryParams: {
                "firstname": "Nic",
                "lastname": "Raboy"
            }
        };
        this.router.navigate(["page2"], navigationExtras);
    }

}

在接收页面中,您将接收以下查询参数:

import {Component} from "@angular/core";
import {ActivatedRoute} from "@angular/router";

@Component({
    selector: "page2",
    template: `
         <span>{{firstname}}</span>
         <span>{{lastname}}</span>
      `,
})
export class Page2Component {

    firstname: string;
    lastname: string;

    public constructor(private route: ActivatedRoute) {
        this.route.queryParams.subscribe(params => {
            this.firstname = params["firstname"];
            this.lastname = params["lastname"];
        });
    }

}

NgRx

最后一种方式更复杂,但功能更强大,那就是使用NgRx。此库不用于数据共享;这是一个强大的状态管理库。我不能用一个简短的例子来解释如何使用它,但是你可以去官方网站阅读相关文档。

对我来说,NgRx Store解决了多个问题。例如,当您必须处理可观察数据时,以及当不同组件分担一些可观察数据的责任时,存储动作和缩减器确保数据修改总是以“正确的方式”执行。

它还为HTTP请求缓存提供了一个可靠的解决方案。您将能够存储请求和它们的响应,这样您就可以验证您发出的请求还没有存储的响应。

    < li>Angular服务层:Redux、RxJs和Ngrx Store -何时使用商店,为什么? < li>Ngrx商店-架构指南
 类似资料:
  • 问题内容: 抱歉,我确定一个基本问题,但似乎无法弄清楚。 说我有这个程序,文件名为: 如何在另一个程序中调用它?我试过了: 而不是“ hello world”,我得到了……过去我通过将第一个文件设为类来做到这一点,但我想知道如何正确导入该函数?如果有帮助,我会在我的真实文件中打印字典 问题答案: 您需要打印调用函数的结果,而不是函数本身: 另外,您可以省略子句,而不是: 如果更方便,也可以使用:

  • 问题内容: 我有一个包含一个按钮的标题组件,并且我希望该按钮在单击时显示另一个组件(模式页面)。 我可以做这样的事情: 这是我的标头组件: 这是我的模态页面组件,单击其他组件上的按钮时应显示该组件页面: 用于模态的库:https : //github.com/marcio/react-skylight 问题答案: 更像这样: 确保在子组件上公开一个方法: 基本上,这是在将SkyLight的方法包装

  • 我有一个异步函数getIdentByInfo,在控制台中,如果我将它记录在这个函数中,就会得到正确的输出。当我在另一个组件中调用它时,它就不工作了,我只得到“未定义”。我知道这与蜂群同步和承诺有关,但我不知道如何解决我的问题。我需要在另一个组件中填充来自http请求的属性的模型类,以便将它们发送到另一个服务

  • 问题内容: 是否可以从另一个(在同一类中,而不是在子类中)调用构造函数?如果是,怎么办?调用另一个构造函数的最佳方法是什么(如果有几种方法可以做到)? 问题答案: 对的,这是可能的: 要链接到特定的超类构造函数而不是同一类中的构造函数,请使用代替。注意,你只能链接到一个构造函数,它必须是构造函数主体中的第一条语句。

  • 问题内容: 我想调用一个在second.js文件的first.js文件中定义的函数。这两个文件都在HTML文件中定义,例如: 我想打电话给在定义中。根据我的搜索结果,答案是首先定义是否可以,但是根据我的测试,我没有找到任何方法。 这是我的代码: 问题答案: 除非在同一文件中定义了该函数,或者在尝试调用该函数之前已加载了该函数,否则无法调用该函数。 除非函数的范围与尝试调用该函数的范围相同或更大,否

  • 我不明白为什么下面的代码会打印两次。我以为应该是个人和学生。当通过“a”对象调用printPerson()内部的getInfo()时,为什么要调用Person类内部的一个,为什么不调用Student类中的一个?提前谢谢。