[英]Is there a way to enable the autocomplete for angular reactive form?
我想为 angular 表单设置autocomplete
属性,但它没有按预期工作。 它只记住我第一次提交的值,无论我点击多少次提交按钮,我都想记住并建议所有值。
这是我尝试过的代码的堆栈闪电战。
<form
autocomplete="on"
(ngSubmit)="onSubmit()"
name="filtersForm"
[formGroup]="formGroup1"
>
<div>
<label>First Name</label>
<input
id="firstName"
name="firstName"
autocomplete="on"
formControlName="firstName"
/>
</div>
<div>
<label>Last Name</label>
<input
id="firstName"
name="lastName"
autocomplete="on"
formControlName="lastName"
/>
</div>
<button type="submit">Submit</button>
</form>
以下是我使用的autocomplete
属性的详细信息。
在 Firefox 中,多次单击提交按钮后,自动完成工作正常,问题出在 Chrome 和 Edge 中。
有没有办法让自动完成功能适用于 angular 表单中的输入?
autocomplete
属性仅适用于提交的值。 它与 Angular 无关。
https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
如果您需要一些自定义行为,那么您最好创建自己的组件来自动完成用户的输入,这样您就可以使用一些默认值,在模糊中添加更多的值等。
您只需要删除输入标签中的autocomplete="on"
即可。 使用 chrome,我们只在表单元素中添加属性autocomplete="on"
,它将缓存用户输入到输入文本中的所有值。 结果将是这样的:
<form
autocomplete="on"
(ngSubmit)="onSubmit()"
name="filtersForm"
[formGroup]="formGroup1"
>
<div>
<label>First Name</label>
<input
id="firstName"
name="firstName"
formControlName="firstName"
/>
</div>
<div>
<label>Last Name</label>
<input
id="firstName"
name="lastName"
formControlName="lastName"
/>
</div>
<button type="submit">Submit</button>
</form>
您必须使用所需选项创建一个数组,该数组应显示为自动完成。 您可以在这里查看https://material.angular.io/components/autocomplete/examples ,有多个示例可以帮助您。 即使你没有使用 Angular 材料,逻辑也是一样的
我想,我找到了一种解决方法,它只适用于模板驱动表单。
我在处理这个问题时发现了什么。
form
提交时, autofill
只记住第一次提交的值form
提交POST
方法可以记住所有值。 是的,从上面看,显然第二种方式适合我们。 但是为什么有人会做表单POST
来向 BE 提交表单。 应该有更好的方法来解决这个问题。 否则我们将不得不考虑处理 PostBack 😃😃(FW like.Net 通过保留隐藏的input
来做到这一点)。
别担心,我们可以在这里做一些解决方法来避免表单POST
。 我找到了在不刷新页面的情况下处理 POST 调用的答案。
使用普通的 HTML 和 JS工作 JSBin
AutoCompleteSaveForm = function(form){
var iframe = document.createElement('iframe');
iframe.name = 'uniqu_asdfaf';
iframe.style.cssText = 'position:absolute; height:1px; top:-100px; left:-100px';
document.body.appendChild(iframe);
var oldTarget = form.target;
var oldAction = form.action;
form.target = 'uniqu_asdfaf';
form.action = '/favicon.ico';
form.submit();
setTimeout(function(){
form.target = oldTarget;
form.action = oldAction;
document.body.removeChild(iframe);
});
}
基本上我们在表单属性上改变了一些东西。
target="iframe_name"
- 连接到 iFrame 以避免页面刷新。method="POST"
- POST 调用url="/favicon"
- API url 到 favicon(轻量级调用)在 angular 中,您可以为其创建一个指令。
import {
Directive, ElementRef, EventEmitter,
HostBinding, HostListener, Input, Output,
} from '@angular/core';
@Directive({
selector: '[postForm]',
})
export class PostFormDirective {
@HostBinding('method') method = 'POST';
@HostListener('submit', ['$event'])
submit($event) {
$event.preventDefault();
this.autoCompleteSaveForm(this.el.nativeElement);
}
constructor(private el: ElementRef) {}
autoCompleteSaveForm(form) {
let iframe = document.querySelector('iframe');
if (!iframe) {
iframe = document.createElement('iframe');
iframe.style.display = 'none';
}
iframe.name = 'uniqu_asdfaf';
document.body.appendChild(iframe);
var oldTarget = form.target;
var oldAction = form.action;
form.target = 'uniqu_asdfaf';
form.action = '/favicon.ico'; // dummy action
form.submit();
setTimeout(() => {
// set back the oldTarget and oldAction
form.target = oldTarget;
form.action = oldAction;
// after form submit
this.onSubmit.emit();
});
}
@Output() onSubmit = new EventEmitter();
ngOnDestroy() {
let iframe = document.querySelector('iframe');
if (iframe) {
document.body.removeChild(iframe);
}
}
}
好的,到目前为止一切顺利。 然后我开始将它集成到formGroup
(模型驱动表单)中,不知何故它不起作用。 下次这些字段时它不会存储值。
<form (ngSubmit)="onSubmit()" [formGroup]="formGroup1" autocomplete="on">
<div>
<label>First Name</label>
<input id="firstName" name="firstName" formControlName="firstName" />
</div>
<div>
<label>Last Name</label>
<input id="lastName" name="lastName" formControlName="lastName" />
</div>
<button>Submit</button>
</form>
后来我用模板驱动表单尝试了同样的方法。 它就像一个魅力。 我没有深入探讨为什么它不适用于 Model 驱动形式(也许调查可能会占用更多时间)
<form #form1="ngForm" ngForm postForm (onSubmit)="onSubmit(form1)">
<ng-container [ngModelGroup]="userForm">
<div>
<label>First Name</label>
<input name="firstName" [(ngModel)]="userForm.firstName" />
</div>
<div>
<label>Last Name</label>
<input name="lastName" [(ngModel)]="userForm.lastName" />
</div>
</ng-container>
<button>Submit</button>
</form>
是的,我刚一开始就说过它只适用于模板驱动表单。 所以你必须切换到模板。 还有一件更重要的事情要注意,您可能会想到创建虚拟 POST api 调用,它可以是轻量级的,而不是点击图标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.