I am using the < mat-progress-bar > like this:
<mat-progress-bar
name="label"
mode="buffer"
[value]="percentage"
[bufferValue]="percentage 10"
>
</mat-progress-bar>
And it generates the following html:
<svg width="100%" height="4" focusable="false" >
<defs>
<pattern x="4" y="0" width="20" height="4" patternUnits="userSpaceOnUse" id="mat-progress-bar-82">
<circle cx="2" cy="2" r="2"></circle>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(whatever)"></rect>
</svg>
The thing is.. I want to modify the attributes width
& r
, for that, i wrote something like:
const patterns = document.getElementsByTagName("pattern")
this.renderer.setAttribute(patterns[0],"width",this.width);
which works BUT, angular itself, somehow, replaces the attributes to its defult value after one "tick"
My question is.. how can I bind width
& r
attributes from that auto-generared svg? or event prevent Angular from updating the attributes
I'm looking for something like:
<mat-progress-bar
...
[attr.svg.defs.pattern.width] = "width"
></mat-progress-bar>
I also try to extend matProgressBar but I don't know where this attributes values are set.
I can't found anything related
UPDATE It works as expected in stackblitz, now I'm more lost than before
@Component({
selector: 'progress-bar-configurable-example',
template: `
<mat-progress-bar
[mode]="'buffer'"
[value]="value"
[bufferValue]="value 10"
>
</mat-progress-bar>`,
styleUrls: ['progress-bar-configurable-example.css'],
})
export class ProgressBarConfigurableExample implements AfterViewInit {
value = 50;
bufferValue = 70;
constructor(private renderer: Renderer2){}
ngAfterViewInit(): void {
const patterns = document.getElementsByTagName("pattern")
this.renderer.setAttribute(patterns[0],"width","30");
setTimeout( ()=> this.value = this.value 20 , 1000)
}
}
CodePudding user response:
Okay, I found the problem.
The *ngFor updates < mat-progress-bar > and i was setting its attributes just in onAfterViewInit
. The fix is something like
@Component({
selector: 'progress-bar-configurable-example',
template: `
<div #progressBars *ngFor="let o of bars">
<mat-progress-bar
[mode]="'buffer'"
[value]="value"
[bufferValue]="value 10"
>
</mat-progress-bar>
<br/>
</div>`,
styleUrls: ['progress-bar-configurable-example.css'],
})
export class ProgressBarConfigurableExample
implements AfterViewInit
{
value = 10;
bufferValue = 70;
bars = [{}, {}];
@ViewChildren('progressBars') progressBars: any;
constructor(private renderer: Renderer2) {}
ngAfterViewInit(): void {
this.progressBars.changes.subscribe(t => {
const patterns = document.getElementsByTagName('pattern');
this.renderer.setAttribute(patterns[0], 'width', '30');
})
}
}
As you can see the key thing is to subscribe to changes in @ViewChildren
and setting the attributes again.
Thanks