Как я могу привязать свойство к проецируемому контенту в angular2?

Я хочу использовать проецирование контента, но не могу заставить его работать.

HTML-код

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

Компонент

@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;
}

Как я могу привязать условие * ngIf в диапазоне к требуемому свойству проецируемого элемента ввода? Цель состоит в том, чтобы показать звездочку во внешнем компоненте, когда [required] становится истинным.

Редактировать: я сделал - не работает - plunkr, чтобы показать что я имею в виду.


person westor    schedule 02.05.2016    source источник


Ответы (2)


Вы можете сослаться на элемент управления в ng-content с помощью декоратора ContentChild:

@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); // <-------
  }
}

Таким образом, у вас будет доступ к свойствам элемента управления и особенно к валидатору. Если у вас есть Validators.required, требуется ваш ввод.

Что мне непонятно, так это то, что вы используете ngFormControl и атрибут required. Я думаю, что вам следует использовать следующее:

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

См. этот вопрос для более подробной информации:

См. также эту статью (раздел «Компонент формы для полей») для более подробной информации:

Изменить

Немного покопавшись, можно проверить, что на входе применяется директива RequiredValidator:

@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();
  }
}
person Thierry Templier    schedule 02.05.2016
comment
Алло, Тьерри, спасибо за быстрый ответ. Я хочу разрешить изменение атрибутов, таких как обязательный или отключенный, контролируемый моим внешним компонентом. Если бы я добавил Validators.required в свою группу formbuilder.group, я бы жестко прописал это, не так ли? Мне кажется, я не могу использовать ваше сравнение с this.state.validator, потому что нет доступной функции проверки, когда я использую для этого атрибут? - person westor; 02.05.2016
comment
Пожалуйста! Итак, вы хотите использовать встроенное объявление валидаторов с ngControl, а не использование FormBuilder? Я спрашиваю, потому что вы используете ngFormModel и ngFormControl... - person Thierry Templier; 02.05.2016
comment
Думаю, я понял ;-) Вы можете проверить, применяется ли RequiredValidator к входу. Я обновил свой ответ соответственно ;-) - person Thierry Templier; 02.05.2016
comment
К сожалению, я до сих пор не могу заставить это работать. Я сделал plunkr, чтобы показать, что я имею в виду. plnkr.co/edit/J3GaJHAjvBeTs3taTtvQ?p=preview — this.requiredValidator является пустым объектом в моем случае. - person westor; 02.05.2016

Поскольку до сих пор я не получил больше ответов, тем временем я попытался найти решение. Я нашел один, который не очень удовлетворяет. Я просто ввожу «требуемый» также во внешний контейнер. Мне не нравится это решение, потому что значение вводится дважды.

И в конце я застрял с новой проблемой. Но вот сначала код:

<my-form-group myLabel="Hallo" [myRequired]="demoForm.controls['required'].value">
    <input type="text" [ngFormControl]="demoForm.controls['hallo']" [required]="demoForm.controls['required'].value">
    errors: {{demoForm.controls['hallo'].errors | json}}
</my-form-group>

И компонент:

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

Моя следующая проблема сейчас: Валидация не обновляется. Пожалуйста, посмотрите этот Plunkr, показывающий также объект ошибок ввода. https://plnkr.co/edit/cBqSB6DX68EnqvnyqrGg?p=preview

Есть ли какое-нибудь решение для этого? (или это просто ошибка?) И, если у кого-то есть лучшее решение, чем мое, я бы с удовольствием.

person westor    schedule 04.05.2016