在Angular2中执行解析器和格式化程序的方式是什么?
在Angular1中,可以使用ngModelController进行此类操作:
//model -> view
ngModelController.$formatters.push(function(modelValue) {
return modelValue.toUpperCase();
});
//view -> model
ngModelController.$parsers.push(function(viewValue) {
return viewValue.toLowerCase();
});
你能给我一个如何用Angular2做的例子吗?
UPD :管道类似于Angular1中的过滤器,但我不是要寻找过滤器,而是寻找
答案 0 :(得分:5)
根据我的说法,Angular 2中没有格式化程序或解析器的概念,但您可以使用以下代码实现它,非常简单
在HTML中
<input type="text" [ngModel] = "formatter(ex)" (ngModelChange)="parser($event)">
代码
export class Component{
data:string = 'data';
constructor(){}
formatter(value){
value = value.toUpperCase(); //manipulate the data according to your need
return value;
}
parser(value){
this.data = value.toLowerCase(); //manipulate the data according to your need
}
}
您还可以根据需要实现$ formatters和$ parsers。
答案 1 :(得分:3)
根据angular 2官方文档,管道被重命名为角度1过滤器。您不能在角度1中使用过滤器将viewModel转换为模型,反之亦然。大多数情况下,您使用过滤器来过滤或格式化模板的数据,而不是用于双向数据传递。
我从未与Angular1合作过,也不知道那些东西是如何运作的。
我认为您正在寻找的是ControlValueAccessor
,它使自定义组件与ngModel
和Angular2表单一起使用,并允许在值的显示和模型格式之间进行映射。
https://github.com/angular/angular/issues/10251#issuecomment-238737954
这是一个比你的问题更复杂的例子,其中一个组件包含一个子表单。组件也可以只是一个表单控件。
Plunker还没有使用现在需要的NgModule
但是应该很容易迁移(我以后会再看看)
验证与管道有什么关系?如果用户更改无效,那么它是否会通过管道传输?这几乎不是什么。
验证与管道完全无关。
我希望看到一个带有验证的自定义组件。组件应具有用户可编辑值的不同表示形式,以及在组件外部传递的模型值的不同表示形式。
上面的Address
组件也实现了自定义验证
来自https://github.com/angular/angular/issues/10251#issuecomment-238737954
中的评论添加验证与值访问器具有类似的过程。您实现验证器接口(只是一个validate()函数)并在自定义窗体控件上将其作为NG_VALIDATOR提供。这是一个例子:
另见
答案 2 :(得分:0)
方法 writeValue(val: T)
和 updateChanges
是您的解析器和格式化器
在 ng2+(老实说从 ng9 项目中获取)看起来更重的 ngModel 扩展,这里是简短的怪物示例(不可运行 - 堆栈溢出不支持 ng2+):
import { Component, forwardRef, Input } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'multi-text-input',
styles: [``],
template: `
<div *ngFor="let val of inputs; let idx = index" style="display: flex">
<input type="text" pInputText [(ngModel)]="val.val" (ngModelChange)="updateChanges()" (mousedown)="onTouched()" />
</div>
`,
// thx to google for this providers section below
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MultiTextInput),
multi: true,
},
],
})
export class MultiTextInput<T = string | string[]> {
inputs: { val: string }[] = [];
@Input() separator = ',';
writeValue(value): void {
value = value || '';
const val: string[] = Array.isArray(value) ? value : value.split(this.separator);
this.inputs = val.filter((val) => val.trim()).map((val) => ({ val }));
this.value = value;
}
updateChanges() {
const arr = this.inputs.map(({ val }) => val.trim()).filter(Boolean);
// ts-ignore to match T, but u don't even need it
// @ts-ignore
this.onChange(Array.isArray(this.value) ? arr : arr.join(this.separator));
}
// thx to google for all generic lines below
value: T;
registerOnChange(fn): void {
this.onChange = fn;
}
registerOnTouched(fn): void {
this.onTouched = fn;
}
onChange: (_: T) => void = (_: T) => {};
onTouched: () => void = () => {};
}
导入,然后 <multi-text-input [(ngModel)]="variable"/>
代替 ngModel 也可以是 formControl 属性。如果这对您不起作用,请发表评论,我会提供更好的样本。
答案 3 :(得分:-2)
在Angular2中,您使用管道。 请参阅文档:https://angular.io/docs/ts/latest/guide/pipes.html