使用指令连接两个输入值
using directive to join two input value
我想 "autofill" 根据其他表单值进行输入。 "id" 应该是 "name" + "." + "combo":
<input matInput name="id" required placeholder="ID" #idValue readonly/>
<input matInput ngModel name="name" required placeholder="NAME" autoFillId />
<mat-form-field>
<mat-select ngModel name="combo" required placeholder="COMBO" autoFillId >
<mat-option value=1>Value 1</mat-option>
<mat-option value=2>Value 2</mat-option>
</mat-select>
</mat-form-field>
这是我的指令:
@Directive({
selector: '[autoFillId]'
})
export class AutoFillDirective {
@Output() idValue: EventEmitter<string> = new EventEmitter();
value: string = ".";
@HostListener('input', ['$event']) onInputChange($event) {
this.value = this.value.split(".")[0] + "." + $event.target.value;
this.idValue.emit(this.value);
}
@HostListener('change', ['$event']) onChange($event) {
this.value = $event.value + "." + this.value.split(".")[1];
this.idValue.emit(this.value);
}
}
它是分开工作的,我的意思是,如果我得到 "undefinded.2" 如果改变了组合,或者 "myName.undefined" 如果改变了输入。
我怎样才能一起做?
所以,我花了一点时间来测试和调试你的代码,这是我发现的:
1) 您正在调用指令的 2 个不同实例
您在组合和输入中调用 autoFillId
,因此它们每个都将有一个 不同的 指令实例。这意味着它们都有不同的 this.value
实例,并且由于两个实例之间永远不会共享该值,因此您将始终只有一侧工作。
2) select
触发输入和更改事件
@HostListener('change', ['$event']) onChange($event) {
this.value = $event.value + "." + this.value.split(".")[1];
this.idValue.emit(this.value);
}
这将在点击 select 时触发。
@HostListener('input', ['$event']) onInputChange($event) {
this.value = this.value.split(".")[0] + "." + $event.target.value;
this.idValue.emit(this.value);
}
这将在select选择一个选项时触发。
这就是导致 undefined
出现的原因。
有多种解决方案可以解决你的问题,如果你想在一个指令上保持这种行为,你必须将更改后的值传递给该指令的另一个实例。
<select name="combo" required placeholder="COMBO" [autoFillId]="currentId" (idValue)="getId($event)">
<option value=1>Value 1</option>
<option value=2>Value 2<option>
<select>
your.component.ts
currentId = "."
getId(event) {
this.currentId = event;
}
autofill.directive.ts
@Directive({
selector: '[autoFillId]'
})
export class AutoFillDirective {
@Output() idValue: EventEmitter<string> = new EventEmitter();
//This input will load the value of the ID when changed
@Input('autoFillId') value: string;
@HostListener('input', ['$event']) onInputChange($event) {
/* We need to check if the event is triggered by the input or the select
We can do this by checking the constructor name for example.
*/
if($event.constructor.name === 'InputEvent') {
this.value = this.value.split(".")[0] + "." + $event.target.value;
} else {
this.value = $event.target.value + "." + this.value.split(".")[1];
}
this.idValue.emit(this.value);
}
}
给你。
您可以在此处查看工作示例:StackBlitz
我想 "autofill" 根据其他表单值进行输入。 "id" 应该是 "name" + "." + "combo":
<input matInput name="id" required placeholder="ID" #idValue readonly/>
<input matInput ngModel name="name" required placeholder="NAME" autoFillId />
<mat-form-field>
<mat-select ngModel name="combo" required placeholder="COMBO" autoFillId >
<mat-option value=1>Value 1</mat-option>
<mat-option value=2>Value 2</mat-option>
</mat-select>
</mat-form-field>
这是我的指令:
@Directive({
selector: '[autoFillId]'
})
export class AutoFillDirective {
@Output() idValue: EventEmitter<string> = new EventEmitter();
value: string = ".";
@HostListener('input', ['$event']) onInputChange($event) {
this.value = this.value.split(".")[0] + "." + $event.target.value;
this.idValue.emit(this.value);
}
@HostListener('change', ['$event']) onChange($event) {
this.value = $event.value + "." + this.value.split(".")[1];
this.idValue.emit(this.value);
}
}
它是分开工作的,我的意思是,如果我得到 "undefinded.2" 如果改变了组合,或者 "myName.undefined" 如果改变了输入。
我怎样才能一起做?
所以,我花了一点时间来测试和调试你的代码,这是我发现的:
1) 您正在调用指令的 2 个不同实例
您在组合和输入中调用 autoFillId
,因此它们每个都将有一个 不同的 指令实例。这意味着它们都有不同的 this.value
实例,并且由于两个实例之间永远不会共享该值,因此您将始终只有一侧工作。
2) select
触发输入和更改事件
@HostListener('change', ['$event']) onChange($event) {
this.value = $event.value + "." + this.value.split(".")[1];
this.idValue.emit(this.value);
}
这将在点击 select 时触发。
@HostListener('input', ['$event']) onInputChange($event) {
this.value = this.value.split(".")[0] + "." + $event.target.value;
this.idValue.emit(this.value);
}
这将在select选择一个选项时触发。
这就是导致 undefined
出现的原因。
有多种解决方案可以解决你的问题,如果你想在一个指令上保持这种行为,你必须将更改后的值传递给该指令的另一个实例。
<select name="combo" required placeholder="COMBO" [autoFillId]="currentId" (idValue)="getId($event)">
<option value=1>Value 1</option>
<option value=2>Value 2<option>
<select>
your.component.ts
currentId = "."
getId(event) {
this.currentId = event;
}
autofill.directive.ts
@Directive({
selector: '[autoFillId]'
})
export class AutoFillDirective {
@Output() idValue: EventEmitter<string> = new EventEmitter();
//This input will load the value of the ID when changed
@Input('autoFillId') value: string;
@HostListener('input', ['$event']) onInputChange($event) {
/* We need to check if the event is triggered by the input or the select
We can do this by checking the constructor name for example.
*/
if($event.constructor.name === 'InputEvent') {
this.value = this.value.split(".")[0] + "." + $event.target.value;
} else {
this.value = $event.target.value + "." + this.value.split(".")[1];
}
this.idValue.emit(this.value);
}
}
给你。 您可以在此处查看工作示例:StackBlitz