【Ionic3】Custom Component

Why we need custom components

Although Ionic Framework has provided us with a lot of components that can meet the most of our needs, we sometimes still have special requirements that can be better realized in our own components.

Create a new component with Ionic CLI

1
$ ionic g component my-comp

The folder of the component will be created at ./src/components/my-comp with my-comp.html, my-comp.scss and my-comp.ts files inside it. The component will have the name of selector as my-comp, and its class name will be MyCompComponent by default.

The component will be added to the file of the Components Module ./src/components/components.module.ts (which will be created automatically if it is the first new component).

Import the component in pages

In the myPage.module.ts file, import the Components module.

1
2
3
4
5
6
7
8
9
10
11
12
...
import { ComponentsModule } from "../../components/components.module";

@NgModule({
...
imports: [
...
ComponentsModule,
...
],
})
...

In the .ts file of the page, import the new component.

1
import { MyCompComponent } from '../../components/my-comp/my-comp';

In the .html file of the page, you can use the tag <my-comp> now in the HTML.

Data binding, updating and event handling

Data input

In my-comp.ts, use the @Input() tag to the properties, so that the properties can be inputted from the page HTML using data binding. get/set can also be used with the Input() tag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
export class MyCompComponent {
param2;

@Input()
param1;

@Input()
get paramTwo() {
return this.param2;
}
set paramTwo(val) {
this.param2 = val;
// something to do
}
...
}

In the HTML file of the page, the data can be inputed as:

1
<my-comp [param1]="myCompParam1" [paramTwo]="myCompParam2"></my-comp>

Data updating

When the component is initialized, the event OnInit will be triggered. When the data input is updated, the event OnChanges will be triggered. The class MyCompComponent can implement the interface OnInit and OnChanges to deal with the event.

1
2
3
4
5
6
7
8
9
10
11
12
export class MyCompComponent implements OnInit, OnChanges {
...

ngOnInit() {
// do something when init
}

ngOnChanges() {
// do something when changed
}
...
}

The timing of data updating and OnChanges events (IMPORTANT)

As angular only check and compare the value of the data input, the following cases of data updating will NOT trigger the OnChanges event.

  • There is the action of assignment (e.g. myCompParam1 = 1;) but the value of the variable is not changed (myCompParam1 is 1 before the assignment).
  • When the input data is an object, the property changes of the object (which will not change the address of the object) will not trigger OnChanges.

Custom events

Custom events can be defined using @Output tag. Suppose the custom component has a close button, and we want to raise a event closeClicked when it is clicked. In my-comp.html, the click event handler is defined, which will be handled in my-comp.ts. Then, in my-comp.ts, a event will be defined and emitted when handling the click event of the button.

1
2
3
4
<div>
...
<button (click)="closeButtonClickHandler($event)"></button>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
export class MyCompComponent implements OnInit, OnChanges {
...

@Output()
closeClicked = new EventEmitter();

closeButtonClickHandler(event) {
this.closeClicked.emit(event);
}

...
}

Get the parameters of the component in the component class

Sometimes we need to know the components’ position or size in the component class. We can import ElementRef in my-comp.ts to get the parameters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { ..., ElementRef } from '@angular/core';

export class MyCompComponent implements OnInit, OnChanges {
...

constructor(private element: ElementRef) {

}
...

someFunction() {
var height = this.element.nativeElement.offsetHeight;
var width = this.element.nativeElement.offsetWidth;
var left = this.element.nativeElement.offsetLeft;
var right = this.element.nativeElement.offsetRight;
var parentHeight = this.element.nativeElement.parentElement.offsetHeight;
var parentWidth = this.element.nativeElement.parentElement.offsetWidth;
// do something
}
}

Call the function/method of the component in the page

Sometimes we need to call the function of the component class in the page. We can import ViewChild in myPage.ts and bind the component with the object of the component class using @ViewChild tag.

1
<my-comp #myComp></my-comp>
1
2
3
4
5
6
7
8
9
import { ViewChild } from '@angular/core';

export class MasterPage {
@ViewChild('myComp') myComp: MyCompComponent;
...
aFunction() {
myComp.someFunction();
}
}

后记

好久没有更新了,技术文档笔记还是要及时写及时更新,否则不用太长时间就会遗忘的。以后尽量多写踩坑心得,加油!