Within a component, I have a property that's an array with some info displayed in a summary as well as an area for making changes. Trying to get the summary data to update as changes are made.
Here's a simplified example...
// discovery.component.ts
@Component({
selector: 'app-discovery',
templateUrl: './discovery.component.html',
styleUrls: ['./discovery.component.scss']
})
export class DiscoveryComponent implements OnInit {
levels = [
{ title: 'title1', rating: 0 },
{ title: 'title2', rating: 3 },
{ title: 'title3', rating: 5 },
]
}
<!--discovery.component.html-->
<!--Summary info-->
<div *ngFor="let level of levels">
{{ level.title }}
{{ level.rating }} <!--Updates when the range slider changes ->
<app-level-display [level]="level.rating"></app-level-display>
</div>
<!--Editing area-->
<div *ngFor="let level of levels; let i = index">
{{ level.title }}
<input type="range" class="form-range" min="0" max="5" name="level{{i}}" [(ngModel)]="level.rating" [value]="level.rating">
{{ level.rating }}
</div>
<!--level-display.component.html-->
<ng-container *ngFor="let level of this.levels">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="#0D4967" class="bi bi-caret-right-fill" viewBox="0 0 16 16">
<defs>
<linearGradient id="gradient1">
<stop class="stop1" offset="0%" stop-color="#74FF87"/>
<stop class="stop2" offset="15%" stop-color="#74FF87"/>
<stop class="stop3" offset="100%" stop-color="#0D4967"/>
</linearGradient>
</defs>
<path d="m7.14,8.753l-5.482,4.796c-0.646,0.566 -1.658,0.106 -1.658,-0.753l0,-9.592a1,1 0 0 1 1.659,-0.753l5.48,4.796a1,1 0 0 1 0,1.506l0.001,0z" fill="url(#gradient1)"/>
</svg>
</ng-container>
// level-display.component.ts
import { Component, OnInit, Input } from '@angular/core'
@Component({
selector: 'app-level-display',
templateUrl: './level-display.component.html',
styleUrls: ['./level-display.component.scss']
})
export class LevelDisplayComponent implements OnInit {
@Input() level: number = 0
levels: number[] = []
constructor() {
}
ngOnInit(): void {
this.levels = Array(this.level).fill(1)
}
}
If I change the slider (input type=range), the summary info updates the reference to {{ level.rating }}
but the component app-rating-viewer
does not.
UPDATE: Looks like all of this stemmed from my establishing the array for app-level-display in ngOnInit(). Changing the component to:
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-level-display',
templateUrl: './level-display.component.html',
styleUrls: ['./level-display.component.scss']
})
export class LevelDisplayComponent implements OnInit {
@Input() level: number = 0
constructor() {
}
iterate(n: number): Array<number> {
return Array(n)
}
ngOnInit(): void {
}
}
fixed the issue.
The best approach I can think of is using ReactiveForms
with the FormArray
clause.
In your component declare the value as a form array, I use FormControl as the value of rating
because you need to update it dynamically:
this.ratingsForm = this.formBuilder.array([
{ title: 'title1', rating: new FormControl(0) },
{ title: 'title2', rating: new FormControl(3) },
{ title: 'title3', rating: new FormControl(5) },
]);
Then in your HTML loop through it as controls
<div *ngFor="let level of this.ratingsForm.controls">
{{ level.value.title }} {{ level.value.rating.value }}
</div>
<!--Editing area-->
<div *ngFor="let level of this.ratingsForm.controls; let i = index">
{{ level.value.title }}
<input type="range" class="form-range" min="0" max="5" name="level{{i}}" [formControl]="level.value.rating">
{{ level.value.rating.value }}
</div>
The formBuilder
comes from a DI on the constructor:
contructor(private formBuilder: FormBuilder)
This is a very simple example, you can refactor it to look better.
Generally speaking, its better to use ReactiveForms
instead of the old ngModel
.
please remove the value attributes
<input type="range" class="form-range" min="0" max="5" name="level{{i}}" [(ngModel)]="level.rating" >
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.