从jquery调用knockout viewmodel函数

从jquery调用knockout viewmodel函数,jquery,asp.net-mvc,asp.net-mvc-4,mvvm,knockout.js,Jquery,Asp.net Mvc,Asp.net Mvc 4,Mvvm,Knockout.js,我知道已经有几个类似的问题了,但是没有一个能帮助我解决问题 我试图使用AJAXPOST上传一个文件,并返回一个包含文件描述的json,然后将其传递给.js文件中的一个knockout viewmodel函数 我可以使用ajax post上传文件: $('.upload-button').click(function () { var formData = new FormData(); var file = document.getElementById

我知道已经有几个类似的问题了,但是没有一个能帮助我解决问题

我试图使用AJAXPOST上传一个文件,并返回一个包含文件描述的json,然后将其传递给.js文件中的一个knockout viewmodel函数

我可以使用ajax post上传文件:

     $('.upload-button').click(function () {
        var formData = new FormData();
        var file = document.getElementById("fileupload").files[0];
        formData.append("FileUpload", file);
        var action = "/QuestionWizard/Upload";

        $.ajax({
            type: "POST",
            url: action,
            data: formData,
            contentType: false,
            processData: false,
            success: function (result) {
                //call viewmodel function here and pass result
            }
        });
    });
这是我的viewmodel函数:

      var ViewModel = function (d, m) {
        var self = this;
        var formData = null;

        self.Model = ko.mapping.fromJS(d, m);



        self.AddDoc = function (data) {
            self.Model.CurrentStep().Files.push({ Name: data.Name, Extension: data.Extension, ContentType: data.ContentType, Size: data.Size, Content: data.Content, FilePath: data.FilePath, Folder: data.Folder });
        }

    }
上载操作:

 [HttpPost]
    public JsonResult Upload() {
        FileUploadModel upload = new FileUploadModel();

        try {

            if (Request.Files != null) {
                HttpPostedFileBase file = Request.Files[0];
                upload.Size = settings.ConvertBytesToMegabytes(file.ContentLength);

                using (var binaryReader = new BinaryReader(Request.Files[0].InputStream)) {
                    upload.Content = binaryReader.ReadBytes(Request.Files[0].ContentLength);
                }

                upload.Name = Path.GetFileName(Request.Files[0].FileName);
                upload.ContentType = Request.Files[0].ContentType;
                upload.Extension = Path.GetExtension(Request.Files[0].FileName);
                upload.Folder = User.Question + "-" + User.Token;
                Transmit.write(ref upload);
            }
        } catch (Exception) {
            return Json(null);
        }
        return Json(upload);
    }
视图中的上载按钮:

 <input type="file" name="fileupload" id="fileupload" data-bind="event:{ change: Upload.bind($data, $element.files[0]) }" />

有人能帮我弄清楚如何调用viewmodel函数并传递生成的json或更好的方法吗


谢谢

您只需要将AJAX移动到视图模型所在的范围内。例如,我通常将我的淘汰代码构造为:

var Namespace = Namespace || {};

Namespace.AppName = (function () {
    var _init = function (data) {
        var viewModel = Namespace.AppName.ViewModel(data);
        ko.applyBindings(viewModel);
        _wireEvents(viewModel);
    };

    var _wireEvents = function (viewModel) {
        // using the example of your AJAX method
        $('.upload-button').click(viewModel.DoUpload);
    };

    return {
        Init: _init
    };
})();
然后,要连接所有内容,只需在视图中执行以下操作:

$(document).ready(function () {
    var data = {}; // any initial data you feed into the view model
    Namespace.AppName.Init(data);
});
由于
.upload按钮
单击处理程序实际上调用了视图模型上的方法,因此您可以直接访问它。例如,在视图模型定义中:

self.DoUpload = function () {
    ...

    $.ajax({
        type: "POST",
        url: action,
        data: formData,
        contentType: false,
        processData: false,
        success: function (result) {
            // use `self` to access any view model observable
        }
    });
};

$('.upload button')
控制器内部不是我认为的最佳实践。。。最好在VM上创建一个函数,并将其绑定到按钮的click事件,否?一点也不。这使用了Knockout对低调事件处理的支持。好吧,他们支持,当然。但是混合和匹配。。。我觉得有点难闻。无论如何,谢谢。