如果数据绑定和文件上传,则非常奇怪

时间:2014-04-23 16:31:48

标签: javascript knockout.js

我注意到在页面上发生了一些非常奇怪的事情,我使用了淘汰赛。情况如下:

    <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变量中没有任何内容,因此,只有一个空的无名文件被回发到服务器。

为什么会发生这种情况?我有什么办法可以缓解这种情况吗?

2 个答案:

答案 0 :(得分:1)

问题是formNode在&#34; instantiation&#34;中不存在当你使用if:binding时。在userHasPermission为true之前,knockout不会生成if:绑定块中的html。如果userHasPermission更改为false,则从DOM中删除HTML。

使用可见绑定,html就在那里,只是隐藏了。

因此,要解决此问题,您可以继续使用注释中记录的可见绑定,或者只需更改上传文件功能以获取每次DOM元素:

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

或任何表格ID。

答案 1 :(得分:0)

想想看,即使你已经解决了它。但if绑定会物理删除元素。因此,您在实例化时传递的表单元素不再存在。