如何从Angular规范触发输入onchange [英] how to trigger input onchange from Angular spec
问题描述
我有一个输入
HTML
File
提交
<input type="file" class="custom-file-input" id="question-file-upload" formControlName="image" (change)="handleFileSelect($event)">
我想对 handleFileSelect
函数进行单元测试.但是我不知道如何触发输入的 onChange
方法.以下是我编写的 spec
,但出现错误 imageInputNE.onchange不是函数
I want to unit test handleFileSelect
function. But I don't know how to trigger the onChange
method of the input. Following is the spec
I have written but I get error imageInputNE.onchange is not a function
fit('should keep track of image counter when an image is loaded', () => {
let newPracticeQuestionComponent = component;
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
let imageInputDE = fixture.debugElement.query(By.css("#question-file-upload"));
expect(imageInputDE).toBeTruthy();
spyOn(newPracticeQuestionComponent,'handleFileSelect');
let imageInputNE:HTMLElement = imageInputDE.nativeElement as HTMLElement;
imageInputNE.onchange(new Event("some event"));
expect(newPracticeQuestionComponent.handleFileSelect).toHaveBeenCalled();
});
推荐答案
请参阅Mozilla网站上的文档,事件通常由外部"源(如Buttons)触发,也可以通过编程方式触发,例如通过调用HTMLElement.元素的click()方法.或通过定义事件,然后使用EventTarget.dispatchEvent()将其发送到指定的目标.
Referring to documentation at Mozilla's website, Events are usually triggered by "external" sources like Buttons, they can also be triggered programmatically, such as by calling the HTMLElement.click() method of an element. or by defining the event, then sending it to a specified target using EventTarget.dispatchEvent().
我认为 click
是一个简单的事件,可以通过编程方式触发,但对于< input type = file ..>
来说,是 change
事件.>更为复杂,因为它需要选择一个文件,转换为博客,更新 files
属性等.因此,可能由于这个原因,我不能简单地调用 imageElementNE.change()
.
I suppose that click
is a simple Event and can be triggered programatically but change
Event for <input type=file..>
is more complicated as it requires selecting a file, converting into a blog, updating files
property etc. So probably for this reason, I cannot just simply call imageElementNE.change()
.
所以我想到了使用 dispatchEvent
,它似乎可以工作
So I thought of using dispatchEvent
and it seem to work
1)我明确创建了一个事件.我想 Event
的构造函数有2个参数,第2个是可选的.
1) I created an Event explicitly. I suppose Event
's constructor takes 2 arguments, 2nd is optional.
来自 https://developer.mozilla.org/zh-CN/docs/Web/API/Event/Event
event = new Event(typeArg, eventInit);
根据文档, typeArg
是表示事件名称的DOMString.换句话说,第一个参数似乎是事件的 type
.当我要发送 change
事件时,我需要将其称为 change
.
From documentation, typeArg
is a DOMString representing the name of the event. In other words, the 1st argument seem to be the type
of the event. As I want to send change
event, I need to call it change
.
For the eventInit
part, I looked at the definition of change
event at https://developer.mozilla.org/en-US/docs/Web/Events/change and picked the values of bubbles
and cancelable
from there
let fileSelectEvent = new Event("change",{bubbles:true,
cancelable: false});
这将创建一个 Event
,其外观如下(我必须承认我不太了解它)
This creates an Event
which looks as follows (I must confess I don't understand much of it)
Event {isTrusted: false, type: "change", target: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, currentTarget: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, eventPhase: 2, …}bubbles: truecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: nulldefaultPrevented: falseeventPhase: 0isTrusted: falsepath: (10) [input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, div#file-upload.custom-file, div.form-group, form#new-question-form.practice-question-form.ng-untouched.ng-pristine.ng-invalid, div#form-div.body__div--background, div#root0, body, html, document, Window]returnValue: truesrcElement: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-validtarget: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-validtimeStamp: 3759.4000000026426type: "change"__proto__: Event
2)创建 Event
后,我在 imageInputNE
上调用了 dispatchEvent
方法.与 EventTarget.dispatchEvent()
相比,我认为这意味着 EventTarget
会触发事件(在我的情况下, imageInputNE
会触发fileSelectEvent
.
2) Once the Event
was created, I called the dispatchEvent
method on imageInputNE
. Comparing with EventTarget.dispatchEvent()
, I think it means that the EventTarget
is triggering the event (in my case imageInputNE
is triggering fileSelectEvent
.
imageInputNE.dispatchEvent(fileSelectEvent);
通过的整个规格是
fit('should keep track of image counter when an image is loaded', () => {
let newPracticeQuestionComponent = component;
expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
let imageInputDE = fixture.debugElement.query(By.css("#question-file-upload"));
expect(imageInputDE).toBeTruthy();
spyOn(newPracticeQuestionComponent,'handleFileSelect');/*.and.callThrough();/*.and.callFake((event)=>{
console.log("fake handleFileSelect called with event",event);
});*/
/*
nativeElemenet hasn'nt got any type. As this program will run in a browser, we can
typecast it to HTMLElement so that we can access prperties and methods of the
corresponding nativeElement
The HTMLElement interface represents any HTML element. Some elements directly
implement this interface, while others implement it via an interface that inherits it.
*/
let imageInputNE = imageInputDE.nativeElement ;
console.log("input element is ",imageInputNE);
console.log("debug element is ",imageInputDE);
//imageInputNE.click();
let fileSelectEvent = new Event("change",{bubbles:true,
cancelable: false});
console.log("created event ",fileSelectEvent);
imageInputNE.dispatchEvent(fileSelectEvent);
expect(newPracticeQuestionComponent.handleFileSelect).toHaveBeenCalled();
});
以上可能不是最好的解决方案,因为我无法在 input
字段中处理 files
,但这是我能想到的最好的方法!
The above might not be the best solution as I can't manipuate files
in the input
field but this is the best I could come up with!
这篇关于如何从Angular规范触发输入onchange的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!