Angular 2 ContentChild 应用 Html 属性 [英] Angular 2 ContentChild Apply Html Attributes

查看:24
本文介绍了Angular 2 ContentChild 应用 Html 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义组件,可将引导程序表单组应用于我的表单字段.在我的组件中,我有以下属性:

import { Component, Input, ContentChild } from '@angular/core';从 '@angular/common' 导入 { NgControl };@成分({选择器:'表单域',模板:`<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'}} 是必需的</span><span *ngIf="state.errors.min">{{label?label:'Value'}} 太小</span>

`})导出类 FormFieldComponent{@输入()标签:字符串;@ContentChild(NgControl) 状态;}

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

<form-field label="名字"><input ngControl="firstName" type="text"></表单域></表单>

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

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

解决方案

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

使用

使其在全球范围内可用

bootstrap(App, [提供(PLATFORM_DIRECTIVES,{useValue:[InputLabel],multi:true})])

@Directive({选择器:['[ngControl]']})导出类 InputLabel {@输入()@HostBinding('attr.placeholder')标签;构造函数(){console.log('InputLabel');}}

FormField 组件中,查询该指令并将来自输入的标签传递给指令(在 ngOnChangesngAfterContentChecked 中) -基本上是 labelstate 可用的第一次出现.

@Component({选择器:'表单域',提供者:[],模板:`<div><ng-content></ng-content>

`,指令:[]})导出类 FormField {@Input() 标签:字符串;@ContentChild(InputLabel) 状态;ngOnChanges() {if(this.label && this.state) {this.state.label = this.label;}}ngAfterContentInit() {if(this.label && this.state) {this.state.label = this.label;}}}

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

@Component({选择器:'我的应用',提供者:[],模板:`<div><h2>你好{{name}}</h2><表格><form-field label="名字"><input ngControl="firstName" type="text"></表单域></表单>

`,指令:[FormField,FORM_DIRECTIVES]})出口类应用{构造函数(FB:FormBuilder){this.name = 'Angular2(发布候选!)'this.form = fb.group({firstName: [""]});}}

Plunker 示例

我选择这种方法是因为我无法通过其他东西(NgControl,...)进行查询并获得对输入元素的引用.

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

I have a custom component that applies bootstrap form group to my form fields. In my component I have below properties:

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

And in my template I use my component like this:

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

I was wondering is there any way to dynamically set the placeholder text for the control through my component?

I want the label to be set as placeholder of the input field i.e.

解决方案

This directive is applied to all input elements that have a ngControl or [ngControl]="..." attribute. It sets the placeholder attribute on the element where it is applied.

It is made globally available using

bootstrap(App, [
  provide(PLATFORM_DIRECTIVES, {useValue: [InputLabel], multi: true})
])

@Directive({
  selector: ['[ngControl]']
})
export class InputLabel {
  @Input()
  @HostBinding('attr.placeholder') 
  label;

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

In the FormField component this directive is queried for and the label from the input is passed to the directive (in ngOnChanges or ngAfterContentChecked - basically the first occurence where label and state are available.

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

This is just to demonstrate how its used:

@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

I choose this approach because I wasn't able to query by something else (NgControl, ...) and get a reference to the input element.

It's not necessary to provide the directive this way. It can also be provided like any other custom directive by adding it to directives: [InputLabel] on the @Component() decorator where it is used.

这篇关于Angular 2 ContentChild 应用 Html 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆