需求:
有一组图片,每张图片对应一个描述。然后这一组图片根据svg fill的不同又分成了2组。
所以现在一共有3组图片,在3个文件夹里。
现在想要在组件father-1和组件father-2种展示,在组件father-1中展示所有图片及其描述,在组件father-2中展示单个的图片及其描述。
当点击组件father-1的图片按钮,按钮样式改变;点击组件father-2的图片按钮,按钮样式不变。
组件child负责展示图片。
展示图片的方法如下:
<!-- child.html -->
<button [ngClass]="
posture.active === postureActive.selected
? 'on'
: ''
"
*ngFor="let posture of postures"
(click)="select(posture.data.src)"
>
<div>
<img src="{{ posture.data.src }}" />
<p>{{ posture.data.type }}</p>
</div>
</button>
<!-- posture.active 为true, 表示图片被选中; img是图片, p是图片的描述 -->
描述图片格式如下:
// child.ts
export enum Posture {
HFS = 'HFS',
HFP = 'HFP',
HFDR = 'HFDR '
}
interface PostureSource {
src: string;
type: Posture;
}
export const POSTURE_SOURCES: PostureSource[] = [
{ src: 'assets/postureState/postureOptional/HFS.svg', type: Posture.HFS },
{ src: 'assets/postureState/postureOptional/FFS.svg', type: Posture.FFS },
{ src: 'assets/postureState/postureOptional/HFDR.svg', type: Posture.HFDR }
];
【下面这个是本文的核心】
对传入child组件的postures处理如下:
// child.ts
enum PostureActive {
disabled = 0,
selected = 1,
unselected = 2
}
interface PostureChange<T extends { src: any }> {
data: T;
active: PostureActive;
}
export class ChildComponent implements OnInit {
protocolState = ProtocolState;
postureActive = PostureActive;
_postures: PostureChange<PostureSource>[] = POSTURE_SOURCES.map(s => ({
data: s,
active: this.postureActive.unselected
}));
@Input() postures: any;
ngOnInit() {
if (typeof this.postures === 'string') {
let currentSource = '';
if (this.postureState === ProtocolState.Started) {
currentSource = `assets/postureState/postureStarted/${this.postures}.svg`;
} else {
currentSource = `assets/postureState/postureUnstart/${this.postures}.svg`;
}
const currentPosture = [
{
src: currentSource,
type: `${this.postures}`
}
];
this.postures = currentPosture.map(s => ({
data: s,
active: this.postureActive.disabled
}));
console.log(
'from father-2: ',
'currentPosture:',
currentPosture,
'after map(): ',
this.postures
);
} else {
this.postures = this._postures;
console.log('from father-1: ', this.postures);
}
console.log(
'@input() postures: ',
this.postures
);
}
}
father-1的控制台打印如下:
father-2的控制台打印如下:
要增加点击选中的功能如下:
// child.ts
select(posture: Posture) {
if (this.postures[0].active !== this.postureActive.disabled) {
this.postures = this.postures.map((a: any) =>
a.data.src === posture
? { ...a, active: this.postureActive.selected }
: { ...a, active: this.postureActive.unselected }
);
}
console.log('select: ', this.postures, '|', posture);
}
点击father-2的按钮,控制台打印如下:
点击 father-1的按钮,控制台打印如下:
father-1的描述如下:
<!-- father-1.html -->
<app-child [postures]="postures"></app-child>
// father-1.ts
postures = ['HFS', 'FFS', 'HFDR'];
father-2的描述如下:
<!-- father-2.html -->
<app-child [postures]="posture"></app-child>
// father-2.ts
posture = 'HFS'; // 这个值应是动态的, 此处为了方便直接赋值