VSO*_*VSO 7 javascript angular
我有以下表单字段,工作正常.通过这种方式,我的意思是当我在字段中键入,粘贴等时fooObj.expDate,实时更新得很好并且验证发生.我有预标签,这对我自己来说很明显.
<pre>{{fooObj.someDate | json}}</pre>
<div class="form-group inline-form__input">
<label for="someDate">Some Date</label>
<input tabindex="2"
type="tel"
class="form-control"
maxlength="7"
placeholder="MM/YY"
formControlName="someDate"
name="someDate"
[(ngModel)]="fooObj.someDate"
someDate>
</div>
Run Code Online (Sandbox Code Playgroud)
但是,我someDate在这个领域有这个指令.该指令拦截粘贴事件.它取消了粘贴事件,对输入进行了一些奇特的格式化,然后执行此操作:
setTimeout(() => {
this.target.value = 'lol fancy date';
}, 3000);
Run Code Online (Sandbox Code Playgroud)
target.value是我的someDate领域.值在输入框内得到了很好的更新(我看到它在输入内的屏幕上发生了变化).但是,fooObj.someDate未更新并且不会进行验证.例如,在超时中设置目标值不会触发与键入/粘贴/任何其他javascript事件相同的验证/对象更新.
Angular docs对此没什么用处:
只有当应用程序响应异步事件(例如击键)时,Angular才会更新绑定(以及屏幕).此示例代码将keyup事件绑定到数字0,可能是最短的模板语句.虽然该语句没有任何用处,但它满足Angular的要求,因此Angular将更新屏幕.
那么,如何从该字段的指令触发字段更新?
编辑:我尝试使用我元素中的代码触发注释中建议的元素上的事件:如何手动触发onchange事件?
运行正常,但不强制该字段更新:
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
this.target.dispatchEvent(evt);
}
else
this.target.fireEvent("onchange");
Run Code Online (Sandbox Code Playgroud)
此外,这里是我得到合成事件的想法,不会触发"正常"的行为作为一个keyDown或任何会(我真的希望我误读或他们错误的这个用例,但它不适用于尝试重新发布粘贴事件):https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces
注意:合成事件没有默认操作.换句话说,虽然上面的脚本将触发粘贴事件,但数据实际上不会粘贴到文档中.
我不知道你指令的细节,但我可以猜测你的意图。首先,我们将订阅valueChanges控件的可观察对象,并避免直接在控件上绑定两种方式,以避免过多的写入和检查:
表单.html
<input tabindex="2"
type="tel"
class="form-control"
maxlength="7"
placeholder="MM/YY"
formControlName="someDate"
name="someDate"
someDate />
Run Code Online (Sandbox Code Playgroud)
表单.ts
这是我们订阅的地方(它可以移出构造函数,取决于您何时制作表单)。
constructor() {
this.myForm = new FormGroup({
someDate: new FormControl(''),
});
this.myForm.controls['someDate'].valueChanges.subscribe(
value => this.fooObj.someDate = value;
);
}
Run Code Online (Sandbox Code Playgroud)
某个日期.directive.ts
该指令会将值写入控件,然后订阅valueChanges将更新我们的模型。这适用于粘贴事件和所有其他事件(因此您可以限制目标事件,但我想至少确保粘贴有效)。
@Directive({
selector: '[someDate]'
})
export class SomeDateDirective{
constructor(private el: ElementRef, private control : NgControl) {
}
@HostListener('input',['$event']) onEvent($event){
$event.preventDefault();
let data = $event.clipboardData.getData('text');
setTimeout(() => {
this.control.control.setValue(data.toUpperCase());
}, 3000);
}
}
Run Code Online (Sandbox Code Playgroud)
更改paste为而不是input仅捕获onpaste事件。这有点奇怪,preventDefault()因为输入实际上消失了一段时间。
这是一个笨蛋:http://plnkr.co/edit/hsisILvtKErBBOXECt8t ?p=preview
| 归档时间: |
|
| 查看次数: |
1882 次 |
| 最近记录: |