简体   繁体   English

根据控制器响应动态更改视图的各个部分

[英]Changing parts of view dynamically based on controller response

I'm looking for best approach suggestions for the below scenario: 我正在寻找以下方案的最佳方法建议:

  • A user can choose one or more csv files to validate(Attachment 1) which on "validate" button click goes through the validation code(showing progress bar till it returns an output). 用户可以选择一个或多个csv文件进行验证(附件1),其中“验证”按钮单击会通过验证代码(显示进度条直到它返回输出)。
  • A return response is either a success message or the error details for each file chosen to validate(Attachment 2) 返回响应是成功消息或选择用于验证的每个文件的错误详细信息(附件2)
  • A successfully validated file can now be uploaded to azure storage with an "Upload" button. 现在可以使用“上传”按钮将成功验证的文件上载到azure存储。

Attachment 1 附件1 在此输入图像描述

Attachment 2 附件2 在此输入图像描述

Now, to make everything asynchronous , my thought is that the view needs to have individual flexible section for each file. 现在,为了使一切都异步 ,我的想法是视图需要为每个文件都有单独的灵活部分。

I'm working with MVC5 razor views with knockout.js, I have decent idea about partial views but I am not certain on how to go about this. 我正在使用knockout.js处理MVC5 razor视图,我对部分视图有不错的想法,但我不确定如何解决这个问题。 If not partial views, then what would be the best approach. 如果不是部分观点,那么最好的方法是什么。

my thought is that the view needs to have individual flexible section for each file 我的想法是视图需要为每个文件都有单独的灵活部分

Kind of, what I think you need is a separate model/class for the files in order to run ajax commands on demand, at least that's how I understood your explanation. 我认为你需要的是一个单独的模型/类文件,以便按需运行ajax命令,至少这是我理解你的解释。

Check out this jsfiddle, I have added some random true/false and string stuff to try and mimic your layout as quickly as possible. 看看这个jsfiddle,我添加了一些随机的true / false和字符串,试着尽可能快地模仿你的布局。 For testing try to use 5 or more files (random generators are kind of finicky in JS). 对于测试尝试使用5个或更多文件(随机生成器在JS中有点挑剔)。

https://jsfiddle.net/n2ne6yLh/10/ https://jsfiddle.net/n2ne6yLh/10/

So essentially you listen for a change event on the file input. 所以基本上你在文件输入上监听一个更改事件。 Map each file to a new model "FileModel" in this case, then push it into the observableArray Files. 在这种情况下,将每个文件映射到新模型“FileModel”,然后将其推入observableArray文件。 Each FileModel houses it's own individual results, validation functions etc. Then the layout takes care of the rest. 每个FileModel都有自己独立的结果,验证功能等。然后布局负责其余部分。

You will have need to look into the FormData Web API in order to do stuff with the files in Javascript. 您需要查看FormData Web API,以便在Javascript中处理文件。 If your clients/users are using outdated browsers there a shims/polyfills for the FormData stuff, jquery and what have you. 如果您的客户/用户使用过时的浏览器,那么FormData的东西,jquery和你有什么垫片/填充。 https://developer.mozilla.org/en-US/docs/Web/API/FormData https://developer.mozilla.org/en-US/docs/Web/API/FormData

 var PageModel = function(r) { var self = this; this.Files = ko.observableArray(); this.FileErrors = ko.computed(function() { return _.some(self.Files(), function(file) { return file.IsValid() === false; }); }); this.ClearFiles = function() { document.getElementById("your-files").value = ""; self.Files([]); }; var control = document.getElementById("your-files"); control.addEventListener("change", function(event) { // When the control has changed, there are new files var i = 0, files = control.files, len = files.length; var form = new FormData(); for (; i < len; i++) { form.append(files[i].name, files[i]); self.Files.push(new FileModel(files[i], files[i])); } }, false); } var FileModel = function(r, fileObject) { var self = this; this.FileObject = fileObject; this.Name = r.name; this.Type = r.type; this.Size = r.size; this.IsValidated = ko.observable(false); this.IsValid = ko.observable(); this.ValidationErrors = ko.observable(); this.ValidateFile = function() { //Do some ajax to validate file //console.log('Doing an ajax thing.') // Randomizers for validation, remove in production var random_boolean = Math.random() >= 0.5; var random_strins = Math.random().toString(36).substring(7); // Set vals based on returned ajax response. self.IsValidated(true); self.IsValid(random_boolean); self.ValidationErrors(random_strins); }; this.UploadFile = function() { alert('uploading this file to the interwebs, yay!') } } window.model = new PageModel(); ko.applyBindings(model); 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div class="container"> <div class="row"> <div class="col-md-6 col-md-push-3"> <div class="form-group"> <div class="input-group"> <input type="file" class="form-control" id="your-files" multiple> <span class="input-group-btn"> <button class="btn btn-info" data-bind="click: ClearFiles">Clear</button> </span> </div> </div> </div> </div> </div> <div class="container-fluid"> <div class="row"> <div class="col-sm-6"> <h4>Validate Files</h4> <!-- ko if: Files().length > 0 --> <table class="table table-condensed table-hover"> <thead> <tr> <th>Name</th> <th>Type</th> <th>Size (bytes)</th> </tr> </thead> <tbody> <!-- ko foreach: Files --> <tr data-bind="css: IsValid() ? 'success' : ''"> <td><span data-bind="text: Name"></span> </td> <td><span data-bind="text: Type"></span> </td> <td><span data-bind="text: Size"></span> </td> <td> <button class="btn btn-sm btn-success" data-bind="click: ValidateFile, visible: !IsValidated()">Validate</button> <button class="btn btn-sm btn-success" data-bind="click: UploadFile, visible: IsValid()">Upload</button> </td> </tr> <!-- /ko --> </tbody> </table> <!-- /ko --> </div> <div class="col-sm-6"> <h4>File Errors</h4> <!-- ko if: FileErrors() --> <table class="table table-hovered"> <thead> <tr> <th>Name</th> <th>Error Message</th> </tr> </thead> <tbody> <!-- ko foreach: Files --> <!-- ko if: IsValid() == false --> <tr> <td data-bind="text: Name"></td> <td data-bind="text: ValidationErrors"></td> </tr> <!-- /ko --> <!-- /ko --> </tbody> </table> <!-- /ko --> </div> </div> </div> 

What about the following simple algorithm 以下简单算法怎么样?
Let's assume in your html you have a < div id="allFiles"> 让我们在你的html中假设你有一个<div id =“allFiles”>

You can write the following in your main view file 您可以在主视图文件中编写以下内容

 function validateFiles(filesToValidate)) {
    foreach(file in filesToValidate)
    {
        var fileDivWithIdTheNameOfTheFile = @Html.RenderPartial("A_View_WithProgressBar",file)  
        allFiles.AddElement(fileDivWithIdTheNameOfTheFile );
        ajax.Get("YourActionThatReturnsAResultView",file)
            .OnSuccess(args)
            {
                FindDivForCurrentFile.ReplaceWith(args.ResultView)
            }

     }
}

This way most of you code is on the ServerSide,all you need is some jquery code to replace parts of the page once a validation of a file has been completed 这样大多数代码都在ServerSide上,只需一些jquery代码就可以在文件验证完成后替换部分页面

Going with a partial view will work. 使用局部视图将起作用。 Just have one partial view with the basic table layout for what you need. 只需要一个具有基本表格布局的局部视图即可满足您的需求。 Then have 然后有

<div id='partial'/>

in your main form that is hidden. 在您隐藏的主窗体中。 Post your file using knockout or jquery to your upload action. 使用knockout或jquery将文件发布到您的上传操作。 Let the action return your partial view. 让动作返回您的局部视图。 Then using knockout or jquery's success callback, do something like this: 然后使用knockout或jquery的成功回调,做这样的事情:

success: function(data) {
             $('#partial').html(data);
          }

to insert your partial view's html 插入部分视图的html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM