Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I bind to property in projected content in angular2?

I want to use content projection, but I can't bring it to work.

The HTML is

<form [ngFormModel]="demoForm" (ngSubmit)="onSubmit()">
  <my-form-group myLabel="Some Label">
    <input type="text" [ngFormControl]="demoForm.controls['someInput'] [required]="true">
  </my-form-group>
</form>

The Component is

@Component({
  selector: 'my-form-group',
  template: `
    <div class="form-group">
      <label>{{myLabel}}<span *ngIf="required">&nbsp;*</span></label>
      <ng-content></ng-content>
    </div>
    `
})

export class MyFormGroup {
  @Input() myLabel: string;
}

How can I bind the *ngIf condition in the span to the required property of projected input element? The goal is to show the asterisk in the outer component, when [required] becomes true.

Edit: I made a - not working - plunkr to show what I mean.

like image 533
westor Avatar asked Oct 18 '22 10:10

westor


1 Answers

You could reference the control within the ng-content using the ContentChild decorator:

@Component({
  selector: 'my-form-group',
  template: `
    <div class="form-group">
      <label>{{myLabel}}<span *ngIf="required">&nbsp;*</span></label>
      <ng-content></ng-content>
    </div>
  `
})
export class MyFormGroup {
  @ContentChild(NgFormControl) state; // <------
  @Input() myLabel: string;

  ngAfterViewInit() {
    this.required = (this.state.validator === Validators.required); // <-------
  }
}

This way you will have access to the control properties and specially the validator. If you have the Validators.required one, your input is required.

What is not clear to me is that you use ngFormControl and the required attribute. I think that you should use the following rather:

this.demoForm = formBuilder.group({
  someInput: ['', Validators.required ]
});

See this question for more details:

  • Check if input control has certain type of vallidator in angular2

See also this article (section "Form component for fields") for more details:

  • http://restlet.com/blog/2016/02/17/implementing-angular2-forms-beyond-basics-part-2/

Edit

After having dug a bit, you can check that the RequiredValidator directive is applied on the input:

@Component({
  selector: 'my-form-group',
  template: `
    <div class="form-group">
      <label>{{myLabel}}<span *ngIf="required">&nbsp;*</span></label>
      <ng-content></ng-content>
    </div>
  `
})
export class MyFormGroup {
  @ContentChild(RequiredValidator) requiredValidator; // <------
  @Input() myLabel: string;

  constructor(private cdr:ChangeDetectorRef) {

  }

  ngAfterViewInit() {
    this.required = (this.requiredValidator != null); // <-------
    this.cdr.detectChanges();
  }
}
like image 138
Thierry Templier Avatar answered Oct 31 '22 16:10

Thierry Templier