4

I have seen similar questions about this but I still do not get it. I have a component witch gets list of items Array<{id: number, name: string}> and a list of "checked" items Array<number>

@Component({
    selector: 'check-list',
    template: `
    <div class="form-check" *ngFor="let item of list">
        <label class="form-check-label">
            <input class="form-check-input" 
                type="checkbox" 
                [checked]="checked.includes(item.id)"
                (change)="onChange.emit({id: item.id, value: $event.target.checked})">
            {{ item.name }}
        </label>
    </div>
    `
})

export class CheckListComponent {
    @Input() list: CheckListItem[];
    @Input() checked: number[];

    @Output() onChange: EventEmitter<any> = new EventEmitter();

    constructor() { }
}

If I update the "checked" list the rendered checkbox list gets updated as well, but if I click some of the checkboxes and then updates the "checked" list it does not render as I expected.

Plunker: https://plnkr.co/edit/YSItU48QflE4GZbj58Ev?p=preview

Click on the two buttons in the plunker and it works as I expect, the checkboxes updates according to the "checked" list. But if I click the "item 2" and then click reset, it does not clear "item 2".

I have also tried using [ngModel] and [attr.checked]. The reason I do not want to use [(ngModel)] is that I also have a @Output() which triggers a server request and then if that fails the checkbox should update or not. I'm using ngrx for states.

UPDATE:

So I was not clear enough in my question that I'm using Redux/ngrx and the list sent in to my check-list-component should not be mutated directly by the component itself. I have updated the component to send back outputs on changes

Heres the new plnker: https://plnkr.co/edit/lMouWapI2lb9U6mS9YMy?p=preview

UPDATE 2:

So the problem I have is that click/check will send an update to a server, and if that fails I want the checkbox to be reset to the previous state. I have added a random bool if the server request is a success or not. Maybe I'm using the wrong type of implementation ide for this.

Plunker: https://plnkr.co/edit/nGyS8oYWVzzRULgzcDQV?p=preview

3
  • Did below answer resolve your issue? Commented Sep 6, 2017 at 13:27
  • Well.. your solution work for the case I posted. I have added a new plunker Commented Sep 11, 2017 at 13:04
  • Maybe, you should have added details initially, or had added new questiuon after closing this. Check this How do I ask a good question?, Cheers!! Commented Sep 11, 2017 at 13:11

1 Answer 1

3

you need to update checked array in the check-list compoennt as well when ever check is changed,

Check List

@Component({
    selector: 'check-list',
    template: `
    <div class="form-check" *ngFor="let item of list">
        <label class="form-check-label">
            <input class="form-check-input" 
                type="checkbox" 
                [checked]="checked.includes(item.id)"
                (change)="onChange.emit({id: item.id, value: $event.target.checked})">
            {{ item.name }}
        </label>
    </div>
    `
})    
export class CheckListComponent {
    @Input() list: CheckListItem[];
    @Input() checked: number[];
    
    @Output() onChange: EventEmitter<any> = new EventEmitter();

    constructor() { }
}

App

@Component({
   selector: 'my-app',
   template: `
    <div>
      <h2>Hello {{name}}</h2>
      <check-list [list]="list" [checked]="checked" 
        (onChange)="updateChecked($event)"></check-list>
      <button (click)="setFirstChecked()">Set First Checked</button>
      <button (click)="resetChecked()">Reset Checked</button>
    </div>
   `
})
export class App {      
  ....
  updateChecked($event) {
    // This will be handled in Redux/ngrx...
    if ($event.value) {
      this.checked.push($event.id);
    } 
    else {
      this.checked = this.checked.filter((i) => i !== $event.id);
    }
  }
  ...
}

Updated the Plunker!!

Sign up to request clarification or add additional context in comments.

5 Comments

Nice dynamic way :)
@Swoox, Thanks.. :)
Was wonder if put more buttons, if it would work. But it did very nice.
Hi, well I will update my question, but the state I'm sending in to my checklist is a Redux immutable state so the component should not update it itself but send back an Event
@Korven, updated answer and Plunker too, updated yours code only , in your Plunker you are checking $event.checked you should be checking $event.value as the emitted object has value. Cheers!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.