问题
I am creating an Angular2 project and having a problem with two-way binding for a checkbox.
I have a class called listItem and List like that:
export class ListItem {
public count: number;
public value: string;
public checked: boolean;
constructor(count: number, value: string, checked: boolean) {
this.count = count;
this.value = value;
this.checked = checked;
}
}
export class MyList{
public category: string;
public listItem : ListItem [];
constructor(category: string, listItem : ListItem []) {
this.category = category;
this.listItem = listItem ;
}
}
and I am calling the list from Azure search which is working correctly. the problem is when I just set the value to a checkbox.
<div *ngFor="let list of myList; let listIndex = index;">
<div *ngFor="let item of list.listItems; let itemIndex = index;">
<input type="checkbox" [name]="list.category + item.value"
(change)="item.checked = !item.checked"
[ngModel]="item.checked" />
</div
</div>
but the value is always false also onClick. I tried to use [(ngModel)] but did not work also. I also tried to make a function:
(change)="oncheck(listIndex, itemIndex)"
oncheck(listIndex: number, itemIndex: number) {
this.myList[listIndex].listItems[itemIndex].checked =
!this.myList[listIndex].listItems[itemIndex].checked;
}
but I received this error:
Cannot assign to read-only property 'checked' of object '[object Object]'
why is that and how to fix it? thank you
回答1:
You could use the material2 md-checkbox directive to create styled elements. In my opinion that is not really two-way binding, its just a combination of 1 way binding in both directions (template - data source and data source - template)
UPDATE: I created a small plnkr to reproduce your situation: http://plnkr.co/edit/cr7TokiqSaBGli7mgCBM
@Component({
selector: 'my-app',
template: `
<div *ngFor="let element of elements; let i = index;">
<span>Val: {{element}}</span>
<input type="checkbox"
[checked]="element" (change)="handleChange(element, i)">
</div>
`,
})
export class App {
elements= [
false,
true,
false,
]:
handleChange(val: boolean, index: number){
console.log("Index: "+index);
console.log("Val: "+val);
this.elements[index] = !val;
}
The elements in the list are correctly rendered, but the change events will in some cases modify the values of incorrect positions in the elements array. Ill take a furhter look later
UPDATE: refactored plnkr
Please check: http://plnkr.co/edit/Ich0g5kzSiQINZjh3VYo
I made some changes to the plnkr that u sent me.
I changed the iteration variables from const to let (considering that their values arent constant during execution of the loops).
As I mentioned before, most likely there are 2 posibilities: the classes in .ts are being transpiled in a wrong way to .js (class members are being setted as readonly by default), or there is something wrong in the way that you are manually mapping the values to class instances.
来源:https://stackoverflow.com/questions/44388276/two-way-binding-on-checkbox-ngfor-angular2