Угловой пользовательский контроль - звездный рейтинг - значение из ввода - PullRequest
0 голосов
/ 11 ноября 2018
<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 и установить количество звездочек на основе этого значения. Я попытался ввести значение и установить его везде, где только мог, но все равно ничего не дало. Если бы вы могли предложить мне, как я могу перейти к установке значения из ввода, я был бы рад :)

1 Ответ

0 голосов
/ 11 ноября 2018

Вы уже внедрили 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...