<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的形式获取值,并根据该值设置星数。我尝试输入该值并将其设置为我可以但仍无效果的任何地方。如果您可以建议我如何继续从输入中设置值,我会很高兴:)
答案 0 :(得分:2)
您已经实现了ControlValueAccessor
,因此应该能够通过ngModel
设置值,这是两个绑定。您不需要任何其他输入即可设置该值。因此,您可以将StarRatingComponent
用作-
<jfg-star-rating [ngModel]="3"></jfg-star-rating>
OR
<jfg-star-rating [(ngModel)]="rating"></jfg-star-rating>
工作副本在这里-https://stackblitz.com/edit/angular-material-sample-vv4s6b