首先,我不是FED(我专注于架构和后端代码)所以我的JQuery不是那么好。如果您对如何改进我的代码有任何建议,那将是受欢迎的。
我正在使用uploadify jQuery插件将图片上传到我的网站。我使用ASP.Net MVC3构建了网站,我正在使用表单的复杂类型(使用编辑器模板)。基本上,我的结构允许我输出对象的枚举,每个对象都有一个uploadify控件,允许上传多个文件。如果你需要看,我可以告诉你这段代码,但基本上我已经实现了Phil Haack IEnumerable<HttpPostedFileBase>
示例here的更高版本。
我已经在onComplete事件中添加了代码,以输出一些额外的表单字段,允许我为每个上传的文件添加标题,然后由MVC自动神奇地绑定到正确的对象。所有这些都很好,虽然我确信有更好的方法可以做到。
我面临的问题是,因为MVC3在可枚举表单字段的命名约定中需要基于零的顺序索引,以便操作方法接受IEnumerable。当我删除其中一个动态创建的表单控件(使用取消按钮)时,索引序列被破坏。
现在 - 因为有多个uploadify元素,每个元素都需要维护自己的索引。我希望能够扩展uploadify插件的每个实例以具有可跟踪的“fileIndex”属性,并且还使用“reindexFiles()”方法扩展它,该方法将遍历所有剩余的控件并重命名&amp;重新认识他们。
我的方法可能很粗糙(评论欢迎!),但这是我到目前为止的代码:
$(document).ready(function () {
var uploadedIndex = 0;
$('div[id$="UploadedImages"]').uploadify({
script: '/ControlPanel/Media/UploadRelatedImages',
auto: true,
fileDesc: 'Image Files (*.jpg;*.jpeg;*.gif;*.png)',
fileExt: '*.jpg;*.jpeg;*.gif;*.png',
buttonText: 'Select Images',
fileDataName: 'files',
multi: true,
removeCompleted: false,
simUploadLimit: 3,
queueSizeLimit: 100,
sizeLimit: 1048576, // 1Mb max limit
onSelectOnce: function (event, data) {
var uploader = $("#" + event.delegateTarget.id);
var mediaFormatID = uploader.closest('.mediaFormat').children('input[type="hidden"][name$="MediaFormatID"]').first().val();
var sd = {
ASPSESSID: $("#ASPSESSID").val(),
AUTHID: $("#AUTHID").val(),
mediaFormatID: mediaFormatID // The first grandparent that ends with MediaFormatID, for the hidden field
};
uploader.uploadifySettings('scriptData', sd);
// TODO : The index needs to be managed per instance
// Reset index (this will reset each time a group of images are uploaded)
uploadedIndex = 0;
},
onComplete: function (event, ID, fileObj, response, data) {
// Get the json response
var json = $.parseJSON(response)[0];
// Get the newly created queue item
var queueItem = $("#" + event.delegateTarget.id + ID);
if (json.HasError) {
// Text error in response - show it and highlight
queueItem.children('.percentage').html('<br/>' + json.ErrorMessage);
queueItem.addClass('uploadifyError');
return false;
}
var textBoxId = event.delegateTarget.id + "_" + uploadedIndex + "__Caption";
var textBoxName = event.delegateTarget.attributes['name'].value + "[" + uploadedIndex + "].Caption";
var hiddenId = event.delegateTarget.id + "_" + uploadedIndex + "__MediaFormatImageID";
var hiddenName = event.delegateTarget.attributes['name'].value + "[" + uploadedIndex + "].MediaFormatImageID";
// Create container
var container = $("<div/>").addClass('captionContainer');
// Create bound hidden field
$('<input />', {
'type': 'hidden',
'id': hiddenId,
'name': hiddenName,
'value': json.MediaFormatImageID
}).appendTo(container);
// Display the image thumb
$("<img/>", {
'src': json.ThumbnailPath
}).appendTo(container);
// Create Textbox label
$('<label />', {
'for': textBoxId
}).text('Image Caption')
.appendTo(container);
// Create bound text box
$('<input />', {
'type': 'text',
'id': textBoxId,
'name': textBoxName,
'maxlength': 100
}).appendTo(container);
// Append container to queue item
container.appendTo(queueItem);
// Increment index
uploadedIndex++;
},
onCancel: function (event, ID, fileObj, data) {
// Delete the file from the server
var uploader = $("#" + event.delegateTarget.id);
// Get image ID from created hidden input
var hiddenId = event.delegateTarget.id + "_" + uploadedIndex + "__MediaFormatImageID";
var hidden = $("#" + hiddenId);
$.ajax({
url: '/ControlPanel/Media/DeleteRelatedImage',
type: "POST",
context: uploader,
data: {
mediaFormatImageID: hidden.val()
},
success: function () {
// TODO: Reindex form images
}
});
}
});
});
onCancel方法不完整且未经测试。正如您所看到的,我正在使用文件名的全局索引,但它不适用于第一个之后的任何uploadify实例,因为索引将从存储的最后一个索引开始,而不是0.我这样做,但是,需要维护每个uploadify元素的索引,因为用户可能会在添加第一批图片后尝试添加更多图片。
我已经查看了jquery的$ .extend()功能,但无法获得任何成功的功能。任何帮助都会一如既往地受到赞赏。
答案 0 :(得分:1)
我面临的问题是,因为MVC3需要从零开始, 可枚举表单的命名约定中的顺序索引 字段,以便动作方法接受IEnumerable。
不一定。在文章的最后看一下this post,更具体地说是非顺序指数:
嗯,这一切都很棒,但是当你做不到时会发生什么 保证提交的值是否会保持顺序索引? 例如,假设您希望在提交之前允许删除行 通过JavaScript的书籍列表。好消息是通过介绍 一个额外的隐藏输入,你可以允许任意索引。在里面 在下面的示例中,我们提供了带有.Index后缀的隐藏输入 我们需要绑定到列表的每个项目。每个人的名字 隐藏的输入是相同的,所以如前所述,这将给出 模型绑定器绑定时要查找的一组很好的索引 列表。
然后看看Steven Sanderson的excellent blog post,其中提出了Html.BeginCollectionItem
扩展方法,可以让你实现这一目标。