Javascript if数据绑定和文件上传的行为非常奇怪

Javascript if数据绑定和文件上传的行为非常奇怪,javascript,knockout.js,Javascript,Knockout.js,我注意到在一个页面上发生了一些非常奇怪的事情,我用敲除来增强它。情况如下: 上传文件 选择文件 每当用户添加文件时,这个小区域会立即将文件发回我的服务器。上传文件的代码如下所示。 //formNode在实例化时被传递到viewmodel中,它只是 //表示该元素的DOM节点 self.uploadFiles=函数(){ 自显示加载(true); event.preventDefault(); var formData=new formData($(formNode)[0]); $.ajax

我注意到在一个页面上发生了一些非常奇怪的事情,我用敲除来增强它。情况如下:


上传文件
选择文件
每当用户添加文件时,这个小区域会立即将文件发回我的服务器。上传文件的代码如下所示。

//formNode在实例化时被传递到viewmodel中,它只是
//表示该元素的DOM节点
self.uploadFiles=函数(){
自显示加载(true);
event.preventDefault();
var formData=new formData($(formNode)[0]);
$.ajax({
url:someUrl,
键入:“POST”,
数据:formData,
async:true,
cache:false,
contentType:false,
processData:false,
成功:某种功能
});
};
所以这很有效。然后,我添加了一个if数据绑定,如下所示:


上传文件
选择文件
现在,用户(假设他们有权限)可以查看上载表单,也可以选择要上载的文件,但是uploadFiles函数现在在formData变量中没有具体化任何内容,因此,除了一个空的、匿名的文件之外,没有任何内容会发布回服务器


知道为什么会这样吗?我能做些什么来缓解这个问题吗?

想想看,即使你已经解决了这个问题。但是if绑定实际删除了元素。因此,在实例化时传递的表单元素不再存在。

问题是,在使用if:binding时,formNode在“实例化”时不存在。if:binding块中的html在userHasPermission为true之前不会通过敲除生成。如果userHasPermission更改为false,则会从DOM中删除HTML

通过可见绑定,html就在那里,只是隐藏了

因此,要解决此问题,您可以继续使用注释中提到的可见绑定,或者只需更改upload files函数即可每次获得DOM元素:

var formData = new FormData($('#document-form')[0]);

或者不管表单ID是什么。

您没有几个表单,例如,$(formNode)返回的表单元素多于1个?据我所知,没有。对不起,直截了当的问题,但是如果将if绑定放在虚拟元素中,您会得到相同的行为吗?我尝试过,事实上它仍然显示相同的行为!非常奇怪。但是,当我将if绑定更改为visible时,解决了我的问题。真的很奇怪。非常感谢你的评论。我喜欢避免在viewmodel中查询DOM,因此我不想使用您提出的解决方案,但是使用可视绑定解决了我的问题。非常感谢。另外,我认为您对不存在的节点的评估并不完全准确。当我在使用formNode变量的行上放置断点并将鼠标悬停在formNode上时,我可以非常清楚地看到元素就在那里,而无需更改所放置的代码。我猜在我调用make my vm和调用ko.applyBindings之前,它在技术上是“存在”的,但是在我调用ko.applyBindings之后,它会根据userHasPermission的值将其删除并重新插入DOM?从技术上讲,您想要的formNode还不存在。这取决于何时调用applyBindings来保存对formNode的引用。我做了一个假设,因为我看不到你的代码。我应该说“可能不存在”,但我描述的击倒行为是正确的。无论哪种方式,您都不能依赖保存的对formNode的引用,因为knockout将在if:绑定中添加和删除DOM的该部分,并且您的引用将无效。只是好奇,当您应用绑定时,userHasPermission的值是什么?如果最初为false,则节点将定义。将被删除,然后在更改为true时再次添加。它实际上是false:)
var formData = new FormData($('#document-form')[0]);