Angular 2 ContentChild应用Html属性

时间:2016-06-10 15:48:00

标签: angular angular2-template angular2-directives angular2-forms

我有一个自定义组件,它将bootstrap表单组应用于我的表单字段。在我的组件中,我有以下属性:

import { Component, Input, ContentChild } from '@angular/core';
import { NgControl } from '@angular/common';

@Component({
    selector: 'form-field',
    template: `
            <div class="form-group" [ngClass]="{'has-error':(state && !state.valid && state.touched)}">
                <label *ngIf="label" [attr.for]="state.name" class="col-sm-3 control-label">{{label}}</label>
                <div class="col-sm-9">
                    <ng-content></ng-content>
                    <div *ngIf="state && !state.valid && state.errors && state.touched" class="help-block text-danger">
                        <span *ngIf="state.errors.required">{{label? label:'This field'}} is required</span>
                        <span *ngIf="state.errors.min">{{label? label:'Value'}} too small</span>
                    </div>
                </div>
            </div>
            `
})
export class FormFieldComponent{
    @Input()
    label: string;

    @ContentChild(NgControl) state;
}

在我的模板中,我使用我的组件:

<form [ngFormModel]="form" (ngSubmit)="onSubmit()" novalidate>
    <form-field label="First Name">
     <input ngControl="firstName" type="text">
    </form-field>
</form>

我想知道有没有办法通过我的组件动态设置控件的占位符文本?

我希望将标签设置为输入字段的占位符,即

2 个答案:

答案 0 :(得分:0)

您可以将标签绑定到&#34;占位符&#34;

form-field label="First Name">
 <input ngControl="firstName" type="text" [attr.placeholder]="label">
</form-field>

答案 1 :(得分:0)

此指令适用于具有ngControl[ngControl]="..."属性的所有输入元素。它在应用它的元素上设置placeholder属性。

使用

全局提供
bootstrap(App, [
  provide(PLATFORM_DIRECTIVES, {useValue: [InputLabel], multi: true})
])
@Directive({
  selector: ['[ngControl]']
})
export class InputLabel {
  @Input()
  @HostBinding('attr.placeholder') 
  label;

  constructor() {
    console.log('InputLabel');
  }
}

FormField组件中查询此指令,并将输入中的标签传递给指令(ngOnChangesngAfterContentChecked - 基本上是label的第一次出现}和state可用。

@Component({
  selector: 'form-field',
  providers: [],
  template: `
    <div>
      <ng-content></ng-content>
    </div>
  `,
  directives: []
})
export class FormField {
  @Input() label: string;
  @ContentChild(InputLabel) state;

  ngOnChanges() {
    if(this.label && this.state) {
      this.state.label = this.label;
    }
  }

  ngAfterContentInit() {
    if(this.label && this.state) {
      this.state.label = this.label;
    }
  }
}

这只是为了演示如何使用它:

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <h2>Hello {{name}}</h2>
<form>      
  <form-field label="First Name">
    <input ngControl="firstName" type="text">
  </form-field>      
</form>
    </div>
  `,
  directives: [FormField, FORM_DIRECTIVES]
})
export class App {

  constructor(fb:FormBuilder) {
    this.name = 'Angular2 (Release Candidate!)'
    this.form = fb.group({firstName: [""]});
  }
}

Plunker example

我选择这种方法是因为我无法通过其他内容查询(NgControl,...)并获得对input元素的引用。

没有必要以这种方式提供指令。它也可以像任何其他自定义指令一样提供,方法是将它添加到使用它的directives: [InputLabel]装饰器上的@Component()