Как получить доступ к методу из app.component из другого компонента?

Я новичок в Typescript и Angular 2. Я попытался найти ответ в Интернете, но кажется, что они не работают для меня.

Скажем, у меня есть app.component, как показано ниже:

export class AppComponent implements OnInit {

    constructor(public _testService: TestService) { }

    listForCart = this._testService.getListForCart();
    cartCount = this.listForCart.length;
    cartPayableAmount = 0;

    ngOnInit() {
        this.computeTotal();
    }

    TestingFunction(){
        console.log("Got here");
    }
}

Теперь я хочу получить доступ к TestingFunction в моем app.component в другом классе, как показано ниже:

export class BuyTestComponent {

    constructor(private _testService: TestService) {
    }

    public pageTitle: string = "ALL PRACTICE TEST SERIES";

    TestHere() {
        // should call TestingFunction() here.....
    }
}

Как это сделать? Пожалуйста, помогите

Ответ 1

Если вам нужен доступ к функции из нескольких мест, подумайте о том, чтобы разместить ее в службе, о которой упоминалось @tibbus.

utility.service.ts

@Injectable()
export class UtilityService{

    TestingFunction(){}
}

Затем убедитесь, что служба указана в массиве providers вашего основного модуля:

app.module.ts

// https://angular.io/docs/ts/latest/guide/ngmodule.html#!#ngmodule-properties
@NgModule({ 
  imports:      [ BrowserModule],
  declarations: [ AppComponent, BuyTestComponent ],
  providers:    [ UtilityService ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Затем вы можете ввести эту услугу в любой компонент, который нуждается в доступе к функции

купить-test.component.ts

@Component(...)
export class BuyTestComponent {

    //inject service into the component
    constructor(private util:UtilityService){}

    TestHere() {
        //access service function
        this.util.TestingFunction();
    }
}

Ответ 2

Angular2 имеет 2 способа связи между 2 компонентами:

  1. Через @Input/@Output, если компоненты имеют отношение Parent-Child
  2. Через сервис

Оба способа подробно описаны в этой статье из документов Angular2: https://angular.io/docs/ts/latest/cookbook/component-communication.html

Ответ 3

Предполагая, что ваш класс AppCompenent сохранен как app.component.ts Затем в вашем классе BuyTestComponent вам необходимо сначала импортировать его AppComponent, как показано ниже

import {AppComponent} from '../app.component';

Предполагая, что оба файла сохранены в одной папке.

Создайте его в своем конструкторе, как показано ниже

constructor(public myapp: AppComponent){}

затем позвоните в свой BuyTestComponent, как показано ниже

this.myapp.testingFunction();

наконец, вам нужно зарегистрировать его в качестве провайдера в вашем app.module.ts

providers: [
 AppComponent,
]

Ответ 4

В большинстве случаев ответ BeetleJuice является правильным решением: использовать функциональность нескольких компонентов в сервисах.

Однако иногда у вас есть однозначно связные компоненты, которые вы хотите подключить в HTML-шаблоне родительского компонента.

В этом случае использование службы будет накладным. К счастью, вы можете использовать ссылочные переменные шаблона (#var)

Допустим, у вас есть всплывающий компонент:

// import...

@Component({
    selector: 'my-popup',
    template: '<div *ngIf="visible"><ng-content></ng-content></div>'
})
export class MyPopupComponent {
    public visible: boolean = false;
    public toggle() {
        this.visible = !this.visible;
    }
}

И компонент переключения, который может запускать всплывающий компонент:

// import...

@Component({
    selector: 'my-popup-toggle',
    template: '<button (click)="popup?.toggle()"><ng-content></ng-content></button>'
})
export class MyPopupToggleComponent {
    @Input('for') popup: MyPopupComponent;
}

Тогда так легко соединить компоненты через HTML:

<div>
    <my-popup #popup1>Good popup</my-popup>
    <my-popup #popup2>Better popup</my-popup>
    <my-popup #popup3>Best popup</my-popup>
</div>
<div>
    <my-popup-toggle [for]="popup1">Toggle the good</my-popup-toggle>
    <my-popup-toggle [for]="popup2">Toggle the better</my-popup-toggle>
    <my-popup-toggle [for]="popup3">Toggle the best</my-popup-toggle>
    <my-popup-toggle [for]="popup3">Toggle the best with another button</my-popup-toggle>
</div>

В очень простых ситуациях вы можете сделать что-то вроде этого:

<div>
    <my-popup #popup4>Best popup II</my-popup>
</div>
<div>
    <button (click)="popup4.show()">Toggle the best II</button>
</div>

В случае необходимости вы также можете получить доступ к ссылочной переменной шаблона из родительского компонента:

// import...

@Component({
    selector: 'my-parent-comonent',
    template: '
        ...<my-popup #popup5>Best popup III</my-popup>...
        ...<my-popup #popup6>Best popup IV</my-popup>...
    '
})
export class MyParentComponent {
     @ViewChild('popup5') popup5: MyPopupComponent;
     @ViewChild('popup5') popup5: MyPopupComponent;
     showPopup5() { this.popup5.show(); }
     showPopup6() { this.popup6.show(); }
}

Ответ 5

Я думаю, что самый простой способ добиться этого - создать статическое свойство в компоненте приложения, которое заполняется при включении onInit.

В app.component


export class AppComponent implements OnInit {
  static myapp;

 ngOnInit() {
    AppComponent.myapp = this;
 }
}

тогда в вашем компоненте

import { AppComponent } from '../../app.component';
export class UsersComponent  implements OnInit {

 ngOnInit() {
    console.log(AppComponent.myapp);
 }
}

Ответ 6

Вы можете использовать такие мероприятия, как:

app.component.ts

import { Events } from 'ionic-angular';
  constructor(public events: Events) {
    events.subscribe('myEvent', () => {
      this.myMethod();
    });
  }

  myMethod() {
    console.log("my method was activated");
  }

anotherclass

import { Events } from 'ionic-angular';
constructor(public events: Events) {
}

callEvent() {
  this.events.publish('myEvent');
}