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

Very strange behavior with if data-bind and file upload

本文关键字:非常 数据绑定 文件 if      更新时间:2023-09-26

我注意到在一个我使用敲除功能的页面上发生了一些非常奇怪的事情。情况如下:

    <div class="col-md-4">
        <h3 class="">Upload Document</h3>
        <form id="document-form">
            <span class="form-group">
                <input type="file" name="files" value="Upload" multiple="" id="input-file" style="display: none;" data-bind="event:{change: uploadFiles}" />
                <label for="input-file" class="btn btn-default">Select Files</label>
            </span>
        </form>
    </div>

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

    //formNode is passed into the viewmodel at time of instantiation, and it is just
    //the DOM node that represents that <form></form> element
    self.uploadFiles = function() {
        self.showLoading(true);
        event.preventDefault();
        var formData = new FormData($(formNode)[0]);
        $.ajax({
            url: someUrl,
            type: 'POST',
            data: formData,
            async: true,
            cache: false,
            contentType: false,
            processData: false,
            success: someFunction
        });
    };

所以这非常有效。然后,我添加了一个if数据绑定到整个事情上,就像这样:

    <div class="col-md-4" data-bind="if: userHasPermission">
        <h3 class="">Upload Document</h3>
        <form id="document-form">
            <span class="form-group">
                <input type="file" name="files" value="Upload" multiple="" id="input-file" style="display: none;" data-bind="event:{change: uploadFiles}" />
                <label for="input-file" class="btn btn-default">Select Files</label>
            </span>
        </form>
    </div>

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

你知道为什么会这样吗?我能做些什么来缓解这种情况吗?

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

有了可见的绑定,html就在那里,只是隐藏起来了。

因此,为了解决这个问题,您可以继续使用注释中提到的可见绑定,也可以简单地更改上传文件功能,每次都获得DOM元素:

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

或者不管表单ID是什么。

尽管你已经解决了它,但仔细想想吧。但是if绑定从物理上删除了元素。因此,您在实例化时传递的表单元素已不存在。