我正在寻找以下方案的最佳方法建议:
现在,为了使所有内容异步,我的想法是视图需要为每个文件都有单独的灵活部分。
我正在使用knockout.js处理MVC5 razor视图,我对部分视图有不错的想法,但我不确定如何解决这个问题。如果不是部分观点,那么最好的方法是什么。
答案 0 :(得分:4)
我的想法是视图需要具有个性化的灵活部分 对于每个文件
我认为你需要的是一个单独的文件模型/类,以便按需运行ajax命令,至少是我理解你的解释。
看看这个jsfiddle,我添加了一些随机的true / false和字符串的东西,试着尽可能快地模仿你的布局。对于测试尝试使用5个或更多文件(随机生成器在JS中有点挑剔)。
https://jsfiddle.net/n2ne6yLh/10/
所以基本上你在文件输入上监听一个更改事件。将每个文件映射到新模型" FileModel"在这种情况下,然后将其推入observableArray文件。每个FileModel都拥有它自己的个人结果,验证功能等。然后布局负责其余部分。
您需要查看FormData Web API才能使用Javascript中的文件。如果您的客户/用户使用过时的浏览器,那么FormData的东西,jquery和你有什么垫片/填充。 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);
&#13;
<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>
&#13;
答案 1 :(得分:2)
以下简单算法如何? 让我们在你的html中假设你有一个&lt; div id =&#34; allFiles&#34;&gt;
您可以在主视图文件中编写以下内容
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)
}
}
}
这样大多数代码都在ServerSide上,只需要一些jquery代码就可以在文件验证完成后替换部分页面
答案 2 :(得分:1)
使用局部视图将起作用。只需要一个具有基本表格布局的局部视图即可满足您的需求。
<?xml version="1.0"?>
<?xml-stylesheet href="catalog.xsl" type="text/xsl"?>
<!DOCTYPE catalog SYSTEM "catalog.dtd">
<catalog>
<product description="Cardigan Sweater" product_image="cardigan.jpg">
<catalog_item Type="Men's">
<item_number>QWZ5671</item_number>
<price>39.95</price>
<size description="Medium">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
<size description="Large">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
</catalog_item>
<catalog_item Type="Women's">
<item_number>RRX9856</item_number>
<price>42.50</price>
<size description="Small">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
</size>
<size description="Medium">
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
<size description="Large">
<color_swatch image="navy_cardigan.jpg">Navy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
<size description="Extra Large">
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
<color_swatch image="black_cardigan.jpg">Black</color_swatch>
</size>
</catalog_item>
<catalog_item Type="BabyGirls">
<item_number>ABC1234</item_number>
<price>30.00</price>
<size description="Small">
<color_swatch image="red_cardigan.jpg"></color_swatch>
</size>
<size description="Medium">
<color_swatch image="pink_cardigan.jpg"></color_swatch>
</size>
<size description="Large">
<color_swatch image="blue_cardigan.jpg"></color_swatch>
</size>
<size description="Extra Large">
<color_swatch image="orange_cardian.jpg"></color_swatch>
</size>
</catalog_item>
<catalog_item Type="BabyBoys">
<item_number>BCD4321</item_number>
<price>30.00</price>
<size description="Small">
<color_swatch image="black_cardigan.jpg"></color_swatch>
</size>
<size description="Medium">
<color_swatch image="grey_cardigan.jpg"></color_swatch>
</size>
<size description="Large">
<color_swatch image="blue_cardigan.jpg"></color_swatch>
</size>
<size description="Extra Large">
<color_swatch image="navy_cardigan.jpg"></color_swatch>
</size>
</catalog_item>
</product>
</catalog>
隐藏在您的主窗体中。使用knockout或jquery将文件发布到您的上传操作。让动作返回您的局部视图。然后使用knockout或jquery的成功回调,做这样的事情:
<div id='partial'/>
插入部分视图的HTML