I am new to Typescript and Angular 2. I tried to look for an answer in the web but it seems they don't work for me.
Say I have an app.component as shown below:
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");
}
}
Now I want to access the TestingFunction in my app.component in other class as shown below:
export class BuyTestComponent {
constructor(private _testService: TestService) {
}
public pageTitle: string = "ALL PRACTICE TEST SERIES";
TestHere() {
// should call TestingFunction() here.....
}
}
How to do that? Please help
If you need access to a function from several places, consider putting it in a service as @tibbus mentioned.
utility.service.ts
@Injectable()
export class UtilityService{
TestingFunction(){}
}
Next, make sure the service is listed in the providers
array of your main module:
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 { }
You can then inject that service in any component that needs access to the function
buy-test.component.ts
@Component(...)
export class BuyTestComponent {
//inject service into the component
constructor(private util:UtilityService){}
TestHere() {
//access service function
this.util.TestingFunction();
}
}
Angular2 has 2 ways to communicate between 2 components :
Both ways are detailed in this article from Angular2 docs : https://angular.io/docs/ts/latest/cookbook/component-communication.html
Assuming your class AppCompenent is saved as app.component.ts Then in your BuyTestComponent class, you need to first import it AppComponent like below
import {AppComponent} from '../app.component';
Assuming both files are saved in the same folder.
Instantiate it in your constructor like below
constructor(public myapp: AppComponent){}
then call it in your BuyTestComponent like below
this.myapp.testingFunction();
lastly, you need to register it as a provider in your app.module.ts
providers: [
AppComponent,
]
In most of the cases BeetleJuice's answer is the right solution: put the cross-component functionality into service(s).
However sometimes you have unequivocally cohesive components, which you want to connect in the parent component's HTML template.
In this case, using a service would be overhead. Luckily you can use the template reference variables (#var)
Let's say you have a popup component:
// 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;
}
}
And a toggle component that can trigger a popup component to toggle:
// import...
@Component({
selector: 'my-popup-toggle',
template: '<button (click)="popup?.toggle()"><ng-content></ng-content></button>'
})
export class MyPopupToggleComponent {
@Input('for') popup: MyPopupComponent;
}
Then it's so easy to connect components across the 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>
In very simple situations you can do something like this too:
<div>
<my-popup #popup4>Best popup II</my-popup>
</div>
<div>
<button (click)="popup4.show()">Toggle the best II</button>
</div>
In case you need, you can also access the template reference variable from the parent component:
// 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(); }
}
I think the simplest way to achieve this is, basically create a static property in the app component that is populated when onInit
In app.component
export class AppComponent implements OnInit {
static myapp;
ngOnInit() {
AppComponent.myapp = this;
}
}
then in your component
import { AppComponent } from '../../app.component';
export class UsersComponent implements OnInit {
ngOnInit() {
console.log(AppComponent.myapp);
}
}
You can use Events like:
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');
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.