1

I have a checkbox component (my own design) and use it like this:

Main component:

 let allowChenge = false;
    let field = {
       text: 'text text text',
       visible: true
    }

checkField(value: boolean, field: any) {
   // when I get value=false 
   if (this.allowChenge) {
      this.field.visible = value;
   } else {
      this.field.visible = true;
   }
}

Main component HTML:

<p-checkbox 
   [value]="field.visible"
   [text]="field.text"
   [readonly]="false"
   (onSelect)="checkField($event, field)"
></p-checkbox>

Checkbox component:

@Component({
    selector: 'p-checkbox',
    template: `
        <div style="float: left;">                        
                <label 
                   class="switch" 
                   [class.checked]="value" 
                   [style.opacity]="readonly ? '0.4' : '1.0'"
                >
                   {{ text }}
                </label>            

        </div>
    `
})
export class CheckBoxComponent {    

    @Input() value: boolean;    
    @Input() readonly: boolean = false;    
    @Input() text: string;    

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

    constructor(public _elRef: ElementRef) {

    }    

    ngOnChanges(changes: any) {
        this.value = changes.value.currentValue;
    }    

    select() {
        if (!this.readonly) {
            this.value = !this.value;
            this.onSelect.emit(this.value);
        }        
    }     
}

I have some cases when I do not need to change field object visible value when I make click on checkbox. When field.visible = true and I make click on ckeckbox, in checkbox this.value become false. Then on parent component I set it back to true. But checkbox indicates with value false.

n00dl3
  • 21,213
  • 7
  • 66
  • 76
Darien Fawkes
  • 3,023
  • 7
  • 24
  • 35
  • I know there is no `ngModel` in your code but it is the same mechanism under the hood : from change detector's point of view, nothing has changed, so you need to use `setTimeout()` – n00dl3 Jul 03 '17 at 13:21
  • I try to use setTimeout() around this.field.visible = true; in parent component. did't help. – Darien Fawkes Jul 03 '17 at 13:23
  • ngModel directive I use on other input-types fields. Here I set class based on value, so while I not use any input -> I do not need to use ngModel directive. – Darien Fawkes Jul 03 '17 at 13:25
  • I never said you should use `ngModel`, I said it is the same mechanism under the hood for such a behavior. – n00dl3 Jul 03 '17 at 13:38

1 Answers1

0

From changes-detector's point of view, nothing has changed, so it does not propagate the change from the parent to the child. I already answered to such a question here :

Angular 2 - Checkbox not kept in sync

You can get more details in the answer like why such a behavior happen (I have drawn a nice schema ^_^ ).

tldr;

checkField(value: boolean, field: any) {   
  this.field.visible = value;
  if (!this.allowChange) {
      setTimeout(()=>this.field.visible = true);
   }
}

Not that it would be better to pass a parameter to the checkbox to avoid selection. why not something like [readonly]="!allowChange" ?

n00dl3
  • 21,213
  • 7
  • 66
  • 76
  • In future I will use this code in – Darien Fawkes Jul 03 '17 at 13:48
  • but you have a `@Input() readonly:boolean` in your checkbox component... – n00dl3 Jul 03 '17 at 13:50
  • Yes this value will be true/false in parent component for all checkboxes in future. – Darien Fawkes Jul 03 '17 at 13:55
  • + ability to use checkbox as standalone component of course. – Darien Fawkes Jul 03 '17 at 13:58
  • not if you use a timeout!!!!!!!!!!!!!!!! https://plnkr.co/edit/gmFd35jUcyvPaL1PCFiN?p=preview – n00dl3 Jul 03 '17 at 14:03
  • When I remove this.field.visible = value; line in checkField function -> my issue. You try to set this.field.visible with new value and when re-set it by setTimeout(()=>this.field.visible = true). There is any option to get code working without set and then re-set value? – Darien Fawkes Jul 03 '17 at 14:13
  • seriously, man this is in the answer... the way is to prevent the guy from clicking the checkbox inside your `p-checkbox` component like using the `readonly` `@Input()` : ``. Otherwise there is no change from change-detector's point of view, so you need to wait for next tick. – n00dl3 Jul 03 '17 at 14:18