Мне тоже пришлось иметь дело с такой же ситуацией. Самым простым решением я придумал, использует модель обертку, подобно:
public class QuestionListModel
{
public IList<QuestionModel> Questions { get; set; }
public IList<QuestionModel> Template
{
get
{
return new List<QuestionModel>
{
new QuestionModel {/* defaults for new question */}
};
}
}
public QuestionListModel()
{
Questions = new List<QuestionModel>();
}
}
Важная часть, является имея шаблон свойство , который также является IEnumerable<T>
того же типа, что и фактической модели вы хотите. Таким образом, авто-нумерация будет выполнена для вас MVC. Таким образом, используя эту модель, вы получаете, свою коллекцию, с нумерацией «Questions_0__Title», и вы также получаете одну строку шаблона с названием «Template_0__Title».
Я держу свою строку шаблона скрытой от пользовательского интерфейса и использую ее при добавлении новой строки.
В бритве вы привязываете шаблон так же, как вы связываете регулярный вопрос, с той лишь разницей, что это было бы в скрытом <div>
. Вам также потребуется связать Count
вашего списка вопросов с скрытым полем. В моем случае у меня есть шаблон редактора для Вопроса, который отображает его внутри <div>
с определенным селектором, для более легкого доступа позже. Так что вы в конечном итоге с что-то подобное:
<div class="templateContainer">
<div class="question">
[Template]
</div>
</div>
<div class="items">
[for each of your items]
<div class="question">
[Question]
</div>
</div>
При добавлении строки, уловка, с помощью JavaScript:
Получить счет от скрытого поля, увеличиваем его.
var counter = $("#QuestionsListCount");
var count = parseInt(counter.val());
count++;
Возьмите весь блок шаблона, клонировать его (с помощью JQuery-х .clone(true)
, например), назовите его как нечто уникальное (используя значение счетчика с шага 1, например), и добавить его в раздел, где ваши вопросы находятся.
var template = $("#templateContainer");
var newItem = template.clone(true);
var newId = "item_" + count;
var newQuestion = newItem.children().first();
newQuestion.attr("id", newId);
newQuestion.appendTo('#items');
Для каждого элемента, такие как входы в вашем новом приложенном блоке (вы можете найти его с новым идентификатором вы присвоенной ему), то заменить IdS => «Template_0» с «Questions__count от шага 2» , а имена => «Шаблон [0]» с «Вопросы [счет с шага 2]».
$("#" + newId + " :input").each(function (index, input) {
input.id = input.id.replace("Template_0", "Questions_" + (count - 1));
input.name = input.name.replace("Template[0]", "Questions[" + (count - 1) + "]");
});
Update скрытое поле для счетчика =>counter.val(count);
- ...
- прибыль!
Теперь, что касается удалений, как я это делаю, это мой ViewModel для него на самом деле имеет IsDeleted
флаг, который я связываться скрытом поле в шаблоне Вопрос редактора, а также. Таким образом, удаления так же просто, как скрыть конкретный вопрос (вопрос селектор подходит), и вы установите для этого поля IsDeleted
значение true. Когда вы возвращаете весь свой список обратно по умолчанию, вы должны отбросить все удаленные (или удалить фактические удаления, в зависимости от вашей исходной модели данных).
Таким образом, я избегаю иметь дело с отдельными способами идентификации удаленных элементов, а также перенумеровать все элементы в пользовательском интерфейсе. Кроме того, вы получаете преимущество, заключающееся в том, что серверный код определяет, что должно произойти при удалении (например, проверка или отмена действия).
Это длинный пост, но реализация на самом деле не такая сложная (или длинная), и ее можно легко использовать в общем виде.
Cheers!
спасибо, но я не думаю, что это сработает. Для привязки модели MVC к удару имена полей формы должны соответствовать свойствам модели. Таким образом, «разделение строки обратно на массив» не является привязкой к модели, но в любом случае это не связующее устройство по умолчанию (вам понадобится пользовательский). – RPM1984
В зависимости от ваших требований. Идея использования deletedIds заключается в привязке к отдельному полю в вашей модели viewmodel. Когда они нажимают кнопку «Удалить», вы удаляете строку на клиенте и обновляете поле deletedIds. Для добавлений вы создаете новую строку с идентификационным значением 0. Связыванию не важно, что такое массив, только если он похож на массив. Затем вы работаете на сервере, какие строки новые, глядя на их идентификаторы. Кроме того, я подозреваю, что MVC, вероятно, не заботится о том, какие числа у вас есть в массиве, если они соответствуют соглашениям об именах. Новые строки могут использовать любой идентификатор. –