我已经创建了一个可重用的Angular组件,如下所示:
export enum ESwitchType {
switch = 'switch',
radio = 'radio',
checkbox = 'checkbox',
}
export type TValidSize = 'sm' | 'md' | 'lg' | 'xl';
@Component({
selector: 'jam-toggle',
template: `
<div
[ngClass]="sizeClass"
class="custom-control custom-switch"
>
<input
(change)="changeValue($event)"
[checked]="checked"
type="checkbox"
class="custom-control-input"
id="customSwitch1"
>
<label class="custom-control-label" for="customSwitch1"></label>
</div>
`,
styleUrls: ['./toggle.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ToggleComponent extends BaseDetachedComponent implements OnInit {
public checked: boolean = false;
public switchType = ESwitchType;
@Output() valueChange: EventEmitter<boolean> = new EventEmitter<boolean>();
@Input() type: ESwitchType;
@Input() size: TValidSize = 'md';
@Input() isDisabled = false;
@Input() set value(value: boolean) {
this.checked = value;
this.detectChanges();
}
get sizeClass(): string {
let classSize = '';
switch (this.type) {
case ESwitchType.switch:
classSize = 'custom-switch-';
break;
case ESwitchType.checkbox:
classSize = 'checkbox-';
break;
case ESwitchType.radio:
classSize = 'custom-radio-';
break;
}
return classSize + this.size;
}
constructor(
protected cdr: ChangeDetectorRef,
) {
super(cdr);
cdr.detach();
}
ngOnInit(): void {
this.detectChanges();
}
changeValue(event: Event): void {
event.stopPropagation();
this.valueChange.emit((event.target as HTMLInputElement).checked);
this.detectChanges();
}
}
html -可重用组件。
这两个"jam-toggle"组件必须为不同的函数触发事件。
<jam-toggle
class="ml-md-4"
[type]="switchType.switch"
[size]="'lg'"
[value]="isHighlightsAutomaticGenerated"
(valueChange)="automaticGeneratedHighlights($event)"
></jam-toggle>
<jam-toggle
class="ml-md-4"
[type]="switchType.switch"
[size]="'md'"
[value]="isPasswordStepVisible"
(valueChange)="togglePasswordStep($event)"
></jam-toggle>
但是(valueChange)参数只为第一个订阅者触发一个事件
行为的视觉示例
如何单独侦听更改。每个组件单独使用吗?
我错过了什么?
Thanks for the help
解决这个问题的方法是为元素分配一个唯一的ID。
细节:库用于惟一性
import { v4 as uuidv4 } from 'uuid'; // <<=== add Universally Unique Identifier
export enum ESwitchType {
switch = 'switch',
radio = 'radio',
checkbox = 'checkbox',
}
export type TValidSize = 'sm' | 'md' | 'lg' | 'xl';
@Component({
selector: 'jam-toggle',
template: `
<div
[ngClass]="sizeClass"
class="custom-control custom-switch"
>
<input
(change)="changeValue($event)"
[checked]="checked"
type="checkbox"
class="custom-control-input"
[id]="inputId" // <<=== add
>
<label class="custom-control-label" [for]="inputId"></label> // <<=== add
</div>
`,
styleUrls: ['./toggle.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ToggleComponent extends BaseDetachedComponent implements OnInit {
public checked: boolean = false;
public switchType = ESwitchType;
private id: string = ''; // <<=== add = Element ID must be unique on the page
@Output() valueChange: EventEmitter<boolean> = new EventEmitter<boolean>();
@Input() type: ESwitchType;
@Input() size: TValidSize = 'md';
@Input() isDisabled = false;
@Input() set value(value: boolean) {
this.checked = value;
this.detectChanges();
}
get sizeClass(): string {
let classSize = '';
switch (this.type) {
case ESwitchType.switch:
classSize = 'custom-switch-';
break;
case ESwitchType.checkbox:
classSize = 'checkbox-';
break;
case ESwitchType.radio:
classSize = 'custom-radio-';
break;
}
return classSize + this.size;
}
/**
* Universally Unique Identifier
*/
get inputId(): string { // <<=== add
return this.id;
}
constructor(
protected cdr: ChangeDetectorRef,
) {
super(cdr);
this.id = uuidv4(); // <<=== add
cdr.detach();
}
ngOnInit(): void {
this.detectChanges();
}
changeValue(event: Event): void {
event.stopPropagation();
this.valueChange.emit((event.target as HTMLInputElement).checked);
this.detectChanges();
}
}
以为例:
- material-checkbox
- material-radio