Reputation: 4617
I have a model that basically is a list of objects, and each of this objects contains a boolean value. These boolean values must be updatable by the user so I wrote a component that creates a checkbox for each object and then I bind this checkbox with the model behind it.
This however is not working! If I check a checkbox, the model it is bound to seems to not be updated at all.
To illustrate my problem, I created a minimal working example:
import {Component, Input, OnInit} from '@angular/core';
@Component({
selector: 'component-test',
template: `
<div *ngIf="!!data">
<div *ngFor="let item of data">
<ion-checkbox ([ngModel])="item.checked"></ion-checkbox>
</div>
</div>
<ion-button (click)="console_log()">print output</ion-button>
`
})
export class TestComponent {
@Input() data: any;
console_log() {
console.log(this.data);
}
}
@Component({
selector: 'page-test',
template: `
<ion-header>
<ion-toolbar color="primary">
<ion-title>
Test
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<component-test [data]="params.data | async"></component-test>
</ion-content>
`
})
export class TestPage implements OnInit {
params: any = {};
async get_data() {
return [{checked: false}, {checked: false}, {checked: false}];
}
ngOnInit() {
this.params['data'] = this.get_data();
}
}
As you can see:
The expected behaviour:
The observed behaviour:
Upvotes: 1
Views: 10487
Reputation: 2034
If anyone else runs into this in angular 4 there seems to be an unsolved issue with this thing, especially if you use event.preventDefault();
. The only hack I found working (this is an old angular, might be different in newer versions) is to use a setTimeout
on the update:
@Component({
selector: "my-component",
template: `
<input
(click)="clickHandler($event)"
[(ngModel)]="_inputValue"
type="checkbox"
/>
`,
})
export class MyComponent {
public _inputValue: boolean = false;
constructor(){}
public clickHandler(event: MouseEvent) {
event.preventDefault();
// some stuff that in might cause a call to the
// `progrematicallyChangeInputValue` method
}
public progrematicallyChangeInputValue (value : boolean )
{
// if there is not enough time between this
// method and the event method firing then the
// input value does not change, and you have to
// use the setTimeout
setTimeout(()=> {
this._inputValue = value
}, 100)
}
}
Upvotes: 0
Reputation: 2795
Bootstrap + Angular example:
<div class="form-check">
<label class="form-check-label">
<input
class="form-check-input"
type="checkbox"
(change)="form.checkbox = !form.checkbox";
changed[exchangeId] = true"
[checked]="form.checkbox"
/>
<span class="form-check-sign"> </span> Agree
</label>
</div>
Upvotes: 1
Reputation: 4617
What worked for me in the end (all other answers are valid as well) is to make sure that the FormsModule is imported in your module.
If the component is lazy loaded, it didn't give an error message but the "lazy module" still requires it.
Upvotes: 1
Reputation: 1767
You code is correct but you have made a little mistake... the ngModel should be written as [(ngModel)] not ([ngModel]) famous line : banana in the box not box in the banana. :)
so the code will be :
<div *ngIf="!!data">
<div *ngFor="let item of data">
<ion-checkbox [(ngModel)]="item.checked"></ion-checkbox>
</div>
</div>
Upvotes: 2
Reputation: 29715
You have written ngModel
incorrectly. Proper way of two way binding syntax is
[(attribute or prop)]
code:
<ion-checkbox [(ngModel)]="item.checked"></ion-checkbox>
Upvotes: 1
Reputation: 739
The ngModel
syntax is wrong because of this the checkbox value is not binded, so please change it like this
<div *ngIf="!!data">
<div *ngFor="let item of data">
<ion-checkbox [(ngModel)]="item.checked"></ion-checkbox>
</div>
</div>
Upvotes: 1