Javascript 如何仅在输入模糊时触发被动表单值更改订阅,并在Angular 2中输入key

Javascript 如何仅在输入模糊时触发被动表单值更改订阅,并在Angular 2中输入key,javascript,forms,angular,typescript,Javascript,Forms,Angular,Typescript,我正在开发一个表单,它应该只在输入模糊或按下enter键时更新一些ui部件。我是一个反应型的狂热粉丝,我正在尝试找出正确的方法。到目前为止,我还没有找到太多关于反应形式的答案。他们中的大多数人都专注于模板驱动的表单。到目前为止,我得到了类似的信息: 表单组件动态表单值在运行时更改(没有可预测的字段名) import{组件,输入,输出,事件发射器, ChangeDetectionStrategy}来自“@angular/core” 从“@angular/forms”导入{FormBuilder、F

我正在开发一个表单,它应该只在输入模糊或按下enter键时更新一些ui部件。我是一个反应型的狂热粉丝,我正在尝试找出正确的方法。到目前为止,我还没有找到太多关于反应形式的答案。他们中的大多数人都专注于模板驱动的表单。到目前为止,我得到了类似的信息:

表单组件动态表单值在运行时更改(没有可预测的字段名)

import{组件,输入,输出,事件发射器,
ChangeDetectionStrategy}来自“@angular/core”
从“@angular/forms”导入{FormBuilder、FormGroup、FormControl}
从“rxjs/Observable”导入{Observable}
从“../../../../config/config”导入{DEBUG}
从“调试”导入*作为调试
//接口
从“../../interfaces/Foo”导入{Foo}
//服务
从“../../services/foo.service”导入{FooService}
//调试
const debugOff=(…any)=>{},debug=debug('app:FooCmp')
@组成部分({
选择器:“foo数据cmp”,
templateUrl:'./foo.data.cmp.html',
changeDetection:ChangeDetectionStrategy.OnPush,
样式URL:['./foo.data.cmp.css']
})
导出类FooDataCmp{
私有_foo:foo[]=null
@输入('foo')
设置foo(foo:foo[]){
这个
DEBUG.input&&DEBUG('input foo:',this.\u foo)
}
get foo():foo[]{
把这个还给我
}
//形式
公共表格:FormGroup
公共食品形式$:可见
private updatedFoo:any[]//更新的表单值
//订阅
私人订阅:任意[]=[]
建造师(
私有formBuilder:formBuilder,
私人餐饮服务:餐饮服务,
) {
DEBUG.constr&&DEBUG('Construct FooDataCmp')
}
恩戈尼尼特(){
DEBUG.init&&DEBUG('Initialise FooDataCmp')
//形式
this.initfoorm()
this.subcribeToFormChanges()
}
恩贡德斯特罗(){
DEBUG.destroy&&DEBUG('destroy FooDataCmp')
this.subscriptions.forEach(sub=>sub.unsubscribe())
}
私有initfoorm(){
DEBUG.cmp&&DEBUG('初始化foo表单')
//构建表单
this.fooForm=this.formBuilder.group(this.\u foo)
//防止第一次击键时出现未定义的错误
this.updatedFoo=这个
}
私有subcribeToFormChanges(){
this.fooForm$=this.fooForm.valueChanges
让sub=this.fooForm$.subscribe(fooForm=>{
DEBUG.cmp&&DEBUG('formchanges fooForm',fooForm)
this.updatedFoo=fooForm
})
this.subscriptions.push(sub)
}
/**
*数据更新过程中的重要步骤
*更新状态存储。
*其他服务/组件订阅到状态存储本身
*/
公共refreshAllFooRelatedData(){
DEBUG.cmp&&DEBUG('Refresh all foo related data')
DEBUG.cmp&&debugOff('Updated foo',this.Updated foo)
this.fooService.refreshAllFooRelatedData(this.updatedFoo)
}
公共刷新AllFooRelatedDataOneNoter(e:KeyboardEvent){
如果(e.keyCode!==13){return}
DEBUG.cmp&&DEBUG('刷新所有与foo相关的数据(按enter键)')
DEBUG.cmp&&debugOff('Updated foo',this.Updated foo)
this.fooService.refreshAllFooRelatedData(this.updatedFoo)
}
公共调试模板(){
DEBUG.render&&DEBUG('render FooDataCmp')
}
}
表单模板

<form [formGroup]="fooForm">
    <table class="list expiries">
            <td *ngFor="let value of foo; let i = index">
                <input type="text" [formControlName]="foo[i]" 
                    (blur)="refreshAllFooRelatedData()" 
                    (keydown)="refreshAllFooRelatedDataOnEnter($event)">
            </td>
    </table>
</form>

{{ debugTemplate() }}

{{debugTemplate()}}

这是一个体面的解决方案还是我错过了一些技巧?我的问题是这样做是否正确。我一直希望找到一些表单API选项来处理此任务。我的方法是在表单的基础上构建,但如果此任务有任何可用的内容,我宁愿使用完整的表单api

您可以将模糊和输入事件合并到主题中,并将其与可观察的值更改合并,以便仅在模糊或输入时触发值。我还没有完全测试代码,只是一个想法,我以前遇到过类似的情况

//组件
this.updateField=新主题()
this.form.get('yourfield').valueChanges.withLatestFrom(updateField).map(res=>res[0]).subscribe()
//html

如果将来有人发现了这一点,实际上在反应式表单中内置了一些东西,即
updateOn
选项:

new FormControl('', {updateOn: 'blur'});
这将导致值更改、验证等仅在模糊组件上触发
// component
public ctrl: FormControl = new FormControl(0, {updateOn: 'blur'});

//html
<input [formControl]="ctrl" (keydown.enter)="$event.target.blur()"/>```
public ctrl:FormControl=newformcontrol(0,{updateOn:'blur'}); //html ```
这是一个体面的解决方案吗。。。?你是在问我们是否喜欢你所做的,还是这不适合你?如果是,问题究竟在哪里?反应形式非常好。我的问题是这样做是否正确。我一直在寻找一些表单API选项来处理这个任务。我的方法是在表单的基础上构建,但是如果这个任务有什么可用的,我宁愿使用完整的表单api。这是一个好主意!我知道有些事情可以做得更好。谢谢该死,事实上我现在意识到我是如此的盲目。。。我将在修改时更新。可观测Ftw!:D@JojoOP已经得到了一个公认的答案。从反应式表单的角度来看,将可观测值与公认的答案相结合并使用模糊更新是最好的解决方案。此外,接受答案中的可观察流甚至没有达到目标。实际上,这只是对模糊进行验证检查,而每次值更改(击键)都会触发值更改。在我看来,这是一个更优雅的解决方案,可以完成原始问题所需的一切。这是一个更好、更简洁的解决方案,解决了我只更新基于模糊的单个字段的目的
// component
public ctrl: FormControl = new FormControl(0, {updateOn: 'blur'});

//html
<input [formControl]="ctrl" (keydown.enter)="$event.target.blur()"/>```