主从组件

有时候一个组件中放太多内容会导致组件太庞大,这时候可以拆分成小组件
使用命令来创建组件:

1
ng generate component detail

这个命令会创建目录src/app/detail
这个目录会包含4个文件:

  • 作为组件样式的 CSS 文件。
  • 作为组件模板的 HTML 文件。
  • 存放组件类 DetailComponent 的 TypeScript 文件。
  • DetailComponent 类的测试文件。

父组件到子组件

在自动生成的detail.component.ts中添加@Input装饰器,这个装饰器可以将外部组件的属性导入到当前组件中来:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { Component, OnInit, Input } from '@angular/core';   //添加了Input

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})
export class DetailComponent implements OnInit {
  @Input() detail: string;  //input装饰器的属性是detail,类型是string
  constructor() { }

  ngOnInit() {
  }

}

然后在对应的html中写入,将detail显示出来:

detail.component.html:

1
<p>detail works!, detail is {{ detail }}</p>

外部组件调用的方法是:

app.component.ts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { Component, OnInit, OnChanges } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent{
  strList: string[] = ["1", "2", "3", "", "1"];
}

这里定义了一个strin的数组,并添加了一些值
html文件中调用:

app.component.html:

1
2
3
<div *ngFor="let str of strList">
    <app-detail [detail]="str"></app-detail>
</div>

这段代码的意思是循环strList中的数据,然后将数据交给detail组件进行处理
“[detail]="str"” 这段就是将循环的数据传入到了detail组件内,detail就是detail组件中用@Input装饰器定义的属性

子组件到父组件

子组件到父组件需要用到output装饰器

在子组件中写入:

detail.component.ts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})
export class DetailComponent implements OnInit {
  @Input() detail: string;
  @Output() onDetailClick = new EventEmitter<string>();
  constructor() { }

  ngOnInit() {
  }

  detailClick(){
    this.onDetailClick.emit(this.detail);
  }
}

detail.component.html:

1
2
<p>detail works!, detail is {{ detail }}</p>
<button (click)="detailClick()">Button</button>

这里定义了一个名为onDetailClick的属性,它的类型是EventEmitter,EventEmitter就是事件触发与事件监听的封装
具体可以参考https://angular.cn/api/core/EventEmitter
这里使用时,效果就是点击按钮之后,会触发onDetailClick事件,然后将detail属性传入

外部组件调用:

app.component.ts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { Component, OnInit, OnChanges } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent{
  strList: string[] = ["1", "2", "3", "", "1"];

  detailClick(event: string){
    alert("detail " + event + " click");
  }
}

app.component.html:

1
2
3
<div *ngFor="let str of strList">
    <app-detail [detail]="str" (onDetailClick)="detailClick($event)"></app-detail>
</div>

这里将子组件的onDetailClick事件绑定到了父组件的detailClick方法上,效果就是按下子组件的button,会弹出对话框然后显示内容