I'm trying to change the value for a Donut chart based on the Input Decorator. I'm able to initialize the value but cannot change it any further.
I'm using <input type="number" [(ngModel)]="complete">
to 2 way data bind the value. But its not working. I think it's not working because, the template is already called and we're changing the data later.
Is there any solution to this.?
Working code: http://plnkr.co/edit/hYlFp1BX8ebixQMqAtNj?p=preview
Parent component code:
@Component({
selector: 'my-app',
providers: [],
template: `
<test-component [complete]="complete"></test-component>
Completed %:<input type="number" [(ngModel)]="complete">
`,
directives: [TestComponent]
})
export class App {
complete:number=40;
constructor(){
}
test(){
this.complete=60;
}
}
The complete
value changes at the parent component are being received by the @Input() complete
at the directive.
Your chart is the one not updating. You'll have to repaint the whole chart everytime the value changes.
My suggestion: make complete
an Observable<integer>
and push a new value everytime the user changes the complete
<input>
.
The relevant changes:
@Component({
...
<test-component [complete]="complete"></test-component>
Completed %:<input type="number" [(ngModel)]="complete">
...
export class App {
complete:number=40;
constructor(){
Becomes:
@Component({
...
<test-component [complete]="completeObs"></test-component>
Completed %:<input type="number" [(ngModel)]="complete"
(ngModelChange)="completeObs.next($event)">
...
export class App {
complete:number=40;
completeObs:Observable<integer> = new BehaviorSubject<integer>(this.complete);
constructor(){
And you need to change the directive as well:
export class TestComponent{
@Input() complete:Observable<integer>;
ngAfterViewInit() {
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var colors=['green','orange'];
var labels=['Completed','Pending'];
this.complete.subscribe((complete) => { // <-- notice it subscribes to the input
let incomplete:integer = 100 - complete;