ngModel 自定义 ValuesAccessor
Posted
技术标签:
【中文标题】ngModel 自定义 ValuesAccessor【英文标题】:ngModel custom ValuesAccessor 【发布时间】:2016-05-01 23:01:32 【问题描述】:关于 ngModel 和 DI 的高级问题。
正如我在这里看到的 = https://github.com/angular/angular/blob/2.0.0-beta.1/modules/angular2/src/common/forms/directives/ng_model.ts#L68 ngModel 等待提供者来自 NG_VALUE_ACCESSOR OpaqueToken。这意味着如果我想创建应该支持 ngModel 绑定的自定义组件,我应该将我的 ValueAccessor 实现传递给 DI。所以我有两个问题。
1) 我该怎么做?
2) <input>
元素的默认 ValueAccessor 是什么?如何让它继续工作并将我的仅用于自定义组件?
顺便说一句,我在这里看到:https://github.com/angular/angular/blob/2.0.0-beta.1/modules/angular2/src/common/forms/directives/shared.ts#L102 defaultValueAccessor 是最后一个。所以这意味着如果我通过 DI 系统全局传递我的 ValueAccessor,而不是默认的永远不会返回。
【问题讨论】:
如何扩展默认功能或将其包装在您的自定义功能中,这样即使您一直使用它,您也可以分叉代码来决定运行这两个功能中的哪一个?跨度> 【参考方案1】:您可以在相应指令的providers
(不推荐使用bindings
)属性中注册这样的自定义ControlValueAccessor
:
const CUSTOM_VALUE_ACCESSOR = CONST_EXPR(new Provider(
NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TagsValueAccessor), multi: true));
@Directive(
selector: 'tags',
host: '(labelsChange)': 'onChange($event)',
providers: [CUSTOM_VALUE_ACCESSOR]
)
export class TagsValueAccessor implements ControlValueAccessor
(...)
那么当你将ngModel
和/或ngFormControl
用于带有选择器tags
的组件时,将自动选择此访问器:
@Component(
(...)
directives: [ TagsComponent, TagsValueAccessor ],
template: `
<tags [(ngModel)]="company.labels"
[ngFormControl]="companyForm.controls.labels"></tags>
`
)
export class DetailsComponent
(...)
此问题中提供了完整示例:Angular 2 custom form input。
希望对你有帮助 蒂埃里
【讨论】:
【参考方案2】:当您可以使用内部 ngModel 时,为什么要创建新的值访问器。
这回答了@Maksim Fomim 的第二个问题
模板:
<div class="form-group" [ngClass]="'has-error' : hasError">
<div><label>label</label></div>
<input type="text" [placeholder]="placeholder" ngModel [ngClass]="invalid: (invalid | async)" [id]="identifier" name="name-input" />
</div>
组件:
export class MyInputComponent
@ViewChild(NgModel) innerNgModel: NgModel;
constructor(ngModel: NgModel)
//First set the valueAccessor of the outerNgModel
this.outerNgModel.valueAccessor = this.innerNgModel.valueAccessor;
//Set the innerNgModel to the outerNgModel
//This will copy all properties like validators, change-events etc.
this.innerNgModel = this.outerNgModel;
用作:
<my-input class="col-sm-6" label="First Name" name="firstname"
[(ngModel)]="user.name" required
minlength="5" maxlength="20"></my-input>
【讨论】:
以上是关于ngModel 自定义 ValuesAccessor的主要内容,如果未能解决你的问题,请参考以下文章