我正在尝试模拟在输入控件上按Enter键时的Tab键按下。为此,我使用了指令:
private el: ElementRef;
@Input() onEnter: string;
constructor(private _el: ElementRef, public renderer: Renderer) {
this.el = this._el;
}
@HostListener('keydown', ['$event']) onKeyDown(e: any) {
if ((e.which === 13 || e.keyCode === 13)) {
e.preventDefault();
const event = new KeyboardEvent("keypress", {
"key": "Tab"
});
this.el.nativeElement.dispatchEvent(event);
............
触发输入键代码,但未发送标签
答案 0 :(得分:2)
如果要使用ENTER聚焦元素,则可以使用指令
@Directive({
selector: '[next-tab]',
})
export class NextTabDirective {
@Input('next-tab') nextControl: any;
@HostListener("keydown.enter", ["$event"])
onEnter(event: KeyboardEvent) {
if (this.nextControl) {
if (this.nextControl.focus) {
this.nextControl.focus();
this.nextControl.select();
event.preventDefault();
return false;
}
}
}
constructor(private control: NgControl) {
}
}
您可以使用
之类的形式 <form (submit)="Submit()">
<input #input0 [next-tab]="input1" />
<input #input1 [next-tab]="input2" />
<!--the last not have [next-tab]-->
<!-an ENTER make a submit -->
<input #input2 />
<button type="button" (click)="cancel()">Cancel</button>
<button type="submit">OK</button>
</form>
我不希望使用这种丑陋的解决方法,但我们可以改善将指令作为下一个标签发送控件数组的指令
@Directive({
selector: '[next-tab]',
})
export class NextTabDirective {
@Input('next-tab') nextControl: any[]; //<--an array of controls
@HostListener("keydown.enter", ["$event"])
onEnter(event: KeyboardEvent) {
//find the nextControl not disabled. We check if c is defined
//This allow us to use *ngIf and not put the control
let nextControl=this.nextControl.find(c=>c && !c.disabled);
if (nextControl) {
if (nextControl.focus) {
nextControl.focus();
nextControl.select();
event.preventDefault();
return false;
}
}
}
constructor(private control: NgControl) {
}
}
表格看起来像
<form (submit)="Submit()">
<!--see that we create an array-->
<input #input0 [next-tab]="[input1,input2,input3]" />
<input #input1 [next-tab]="[input2,input3]" />
<!--if only one element, we make an array of one element-->
<input #input2 [style.display]="existInput2?'inherit':'none'" [next-tab]="[input3]" />
<!--if we want make invisible control NOT use *nfIf, therefore, we must hidden and disabled too -->
<input #input3 />
<button type="button" (click)="cancel()">Cancel</button>
<button type="submit">OK</button>
</form>
最后,我在https://stackblitz.com/edit/angular-v8fkkf中放了一个堆叠闪电弹
答案 1 :(得分:1)
还有一种更“合适的方式来执行”下一个选项卡” 这个想法是next-tab指令具有两个变量“ self”和“ next-control”。我们不使用@Input,指令就像
@Directive({
selector: '[next-tab]',
})
export class NextTabDirective {
self:any;
nextControl:any; //See that is not a @Input
@HostListener("keydown.enter", ["$event"])
onEnter(event: KeyboardEvent) {
if (this.nextControl) {
if (this.nextControl.focus) {
this.nextControl.focus();
this.nextControl.select();
event.preventDefault();
return false;
}
}
}
constructor(private control: ElementRef) {
//we store in "self" the native element. This make us easy refered to
//html properties of control
this.self=control.nativeElement;
}
}
在.html中,该伪指令只是next-tab,不是[next-tab],也不是[next-tab] =“”。考虑到input4太用指令“装饰”了,并且所有输入都具有“ name” html属性
<form [formGroup]="myForm" (submit)="submit(myForm)">
<p>
<input type="checkbox" formControlName="ckDisabled"/>Disabled input 2
</p>
<p>
<input type="checkbox" formControlName="ckInvisible"/>Invisible input 3
</p>
<p>
Input 1: <input name="input1" formControlName="input1"
next-tab/>
</p>
<p>
Input 2: <input name="input2" formControlName="input2" tabindex=""
[enableControl]="!myForm.controls['ckDisabled'].value"
next-tab/>
</p>
<p [style.display]="myForm.controls['ckInvisible'].value?'none':'inherit'">
Input 3: <input name="input3" formControlName="input3"
[enableControl]="!myForm.controls['ckInvisible'].value"
next-tab
/>
</p>
<p>
Input 4: <input name="input4" next-tab formControlName="input4"/>
</p>
<p>
<button>OK</button>
</p>
</form>
现在是.ts。我们使用ViewChildren获取具有next-tab指令的所有元素。
export class AppComponent implements OnInit,AfterViewInit {
//We use a ViewChildren to get all the controls width NextTabDirective
//We use QueryList<NextTabDirective>. So the elements of "inputs"
//will have the properties: self and nextControl
@ViewChildren(NextTabDirective) inputs: QueryList<NextTabDirective>;
myForm:FormGroup;
constructor(private fb:FormBuilder){}
//in ngAfterViewInit we asing to nextControl, the self of the next control
ngAfterViewInit() {
const controls=this.inputs.toArray();
//controls will be [input1,input2,input3,input4]
for (let i=0;i<controls.length-1;i++)
controls[i].nextControl=controls[i+1].self; }
}
ngOnInit()
{
this.myForm=this.fb.group({
ckDisabled:false,
ckInvisible:false,
input1:'',
input2:'',
input3:'',
input4:''
});
this.onChanges();
}
onChanges()
{
this.myForm.valueChanges.subscribe((value)=>{
if (this.inputs)
{
//see how we get the control using self.name
const input1=this.inputs.find(c=>c.self.name=="input1");
const input2=this.inputs.find(c=>c.self.name=="input2");
const input3=this.inputs.find(c=>c.self.name=="input3");
const input4=this.inputs.find(c=>c.self.name=="input4");
input1.nextControl=(value.ckDisabled && value.ckInvisible)?input4.self:
(value.ckDisabled)?input3.self:input2.self;
input2.nextControl=(value.ckInvisible)?input4.self:input3.self;
}
})
}
submit(form:any)
{
if (form.valid)
alert("Fom submitted!!")
}
}
https://stackblitz.com/edit/angular-dzdxmh中有一个stackBlitz
答案 2 :(得分:0)
非常简单,不需要自定义指令或任何依赖:
为您的输入指定一个“#Name”并使用 (keyup.enter) 本机指令
<mat-form-field>
<mat-label>xxxx</mat-label>
<input matInput [(ngModel)]="xxxx" name="xxxx" #xxxxInput (keyup.enter)="yyyyInput.focus()">
</mat-form-field>
<mat-form-field>
<mat-label>yyyy</mat-label>
<input matInput [(ngModel)]="yyyy" name="yyyy" #yyyyInput (keyup.enter)="zzzzInput.focus()">
</mat-form-field>
<mat-form-field>
<mat-label>zzzz</mat-label>
<input matInput [(ngModel)]="zzzz" name="zzzz" #zzzzInput>
</mat-form-field>