angular - 角度自定义控件 - 星级 - 来自输入的值
问题描述
<div class="rating">
<div style="display: inline-block"
*ngFor="let starred of stars; let i = index"
(click)="rate(i + (starred ? (value > i + 1 ? 1 : 0) : 1))">
<ng-container *ngIf="starred; else noStar"><mat-icon class="filled">star</mat-icon></ng-container>
<ng-template #noStar><mat-icon class="empty">star_outline</mat-icon></ng-template>
</div>
</div>
@Component({
selector: 'jfg-star-rating',
templateUrl: './star-rating.component.html',
styleUrls: ['./star-rating.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => StarRatingComponent),
multi: true
}
]
})
export class StarRatingComponent implements ControlValueAccessor{
stars: boolean[] = Array(3).fill(true);
// Allow the input to be disabled, and when it is make it somewhat transparent.
@Input() disabled = false;
@HostBinding('style.opacity')
get opacity() {
return this.disabled ? 1 : 1;
}
// Function to call when the rating changes.
onChange = (rating: number) => {
};
// Function to call when the input is touched (when a star is clicked).
onTouched = () => {
};
get value(): number {
if(!this.disabled){
return this.stars.reduce((total, starred) => {
return total + (starred ? 1 : 0);
}, 0);
}
}
rate(rating: number) {
if (!this.disabled) {
this.writeValue(rating);
}
}
// Allows Angular to update the model (rating).
// Update the model and changes needed for the view here.
writeValue(rating: number): void {
if (!this.disabled) {
this.stars = this.stars.map((_, i) => rating > i);
this.onChange(this.value);
}
}
// Allows Angular to register a function to call when the model (rating) changes.
// Save the function as a property to call later here.
registerOnChange(fn: (rating: number) => void): void {
this.onChange = fn;
}
// Allows Angular to register a function to call when the input has been touched.
// Save the function as a property to call later here.
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
// Allows Angular to disable the input.
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
}
}
我正在尝试制作星级组件。我让它作为输入正常工作。所以我可以按下星星以获得正确的值作为 formControl 并将其传递给我的服务。但我的问题是我试图让我的组件作为@input 获取值并根据该值设置星数。我已经尝试输入值并将其设置在我可以设置的任何地方,但仍然没有效果。如果您能建议我如何继续从输入中设置值,我会很高兴:)
解决方案
您已经实现ControlValueAccessor
了,因此您应该能够设置ngModel
两个绑定的值。您不需要任何其他输入来设置该值。所以你可以使用你StarRatingComponent
的 -
<jfg-star-rating [ngModel]="3"></jfg-star-rating>
或者
<jfg-star-rating [(ngModel)]="rating"></jfg-star-rating>
工作副本在这里 - https://stackblitz.com/edit/angular-material-sample-vv4s6b
推荐阅读
- sql - 为什么我不能得到百分比计算?
- javascript - 光滑的滑块在引导下拉菜单中不起作用
- qt - 为什么 Qt c 文件只有标头包含而没有实现代码?
- kiwi-tcms - kiwi tcms 有 Node.js api 吗?
- c# - 将 tif 文件转换为 base64 编码时出现 OutOfMemory 异常
- android - 将数据从 BroadcastReceiver 传递到 ViewModel 或 Repository
- javascript - Canvas getImageData 没有得到目标区域
- pandas - 在操作之前或之后使用 iloc() 时,DataFrame 上的 Log1p 和其他 numpy 函数不会产生相同的结果
- validation - 使用模型验证视图模型
- prometheus - 如何获取查询步骤或计算返回的数据点