Как программно добавлять \ удалять строки из таблицы, которая связывается с данными модели из контроллера в Asp.NET MVC - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть страница Asp.NET MVC, модель которой похожа на

namespace Sample.Models
{
    public class ContModel
    {
        [Display(Name = "Name")]
        public string Name { get; set; }

        [Display(Name = "Code")]
        public string Code { get; set; }

        [Display(Name = "Customer")]
        public string Customer { get; set; }

        public List<Order> Orders { get; set;}
    }

    public class Order
    {
        public string OrderId;
        public string OrderDesc;
    }
}

Я успешно связал данные модели, используя эту статью https://www.pluralsight.com/guides/asp.net-mvc-getting-default-data-binding-right-for-hierarchical-views

Пример, приведенный в статье, использует for цикл и @Html.TextBoxFor для формирования таблицы. Теперь я хочу добавить \ удалить строки программно.

Пока что все примеры, о которых я говорил, вставляют строки с помощью jQuery. И все строки таблицы формируются в виде строки JSON и передаются в контроллер с помощью вызовов AJAX.

Является ли AJAX единственным способом сделать это? Есть ли правильный способ связать данные вновь добавленных строк, чтобы они автоматически передавались при отправке формы с использованием POST?

1 Ответ

0 голосов
/ 26 апреля 2019

Хорошо, для начала, отказ от ответственности: я не тестировал приведенный ниже код, возможно, он немного неполон и может не работать из коробки. Но основные концепции - это все, что, я думаю, приведет вас туда, куда вы хотите пойти, с небольшой прикладной мыслью.

Кроме того, я не совсем уверен в том, что произойдет, если значения индекса элементов, привязываемых к списку во время привязки модели, не в порядке или отсутствуют (например, если у вас есть список из 3 заказов и вы удалите В строке с индексом 2 у вас будет список с привязанными индексами 1 и 3, как он создает список с отсутствующими 2 - вам придется проверить это самостоятельно.)

Если вы протестируете его и обнаружите, что есть проблема, тогда вам, возможно, придется переосмыслить мою быструю попытку сохранить переменную counter и, возможно, переиндексировать имена элементов в существующем html при удалении строки. - вы, вероятно, можете полностью покончить с переменной counter, если вы использовали глобальную переменную в своем javascript, которая будет сохранять значение в течение всей жизни этой страницы, но прошло много времени с тех пор, как я сделал что-то подобное, и пока я, кажется, помните, что это работает, я не могу сказать наверняка.

Стирание: При удалении вам нужно знать, как что удаляется. Есть два способа, которые быстро приходят на ум;

  1. Вы можете проверить свою базу данных, как только у вас появится модель в контроллере, какие элементы есть в вашей базе данных, а какие нет в списке, а затем удалить отсутствующие в списке из базы данных. .

  2. Когда элемент удаляется, вы сохраняете OrderId в другом скрытом вводе в строке через запятую, например «3,25,100», и также привязываете к вашей модели. Таким образом, когда у вас есть модель в вашем контроллере, вы можете просто разделить запятую, пройти через массив и удалить соответствующие ордера.

Я уверен, что есть ряд других способов сделать это.

<table>
    <thead>
        <tr>
            <th></th>
            <th>Description</th>
            <th><button id="AddOrder">Add Order></button></th>
        </tr>
    </thead>
    <tbody id="tableBody">
@for (int i = 0; i < Model.Orders.Count(); i++)
{
    var item = Model.Orders[i];

        <tr id="Order-@item.OrderId">
            <td>
                <button type="button" data-id="@item.OrderId" class="removeOrderBtn"></button>
                @* The trick to model binding with a list is the name attribute matching the Property Name on the model and giving it an index as below *@
                <input type="hidden" name="Orders[@i].OrderId" value="@item.OrderId" />
            </td>
            <td>
                @item.OrderDesc
                <input type="hidden" name="Orders[@i].OrderDesc" value="@item.OrderDesc" id="OrderDesc-@item.OrderId" />
            </td>
        </tr>

}
    </tbody>
</table>
@*Store the value of the last index in this input to keep track of it constantly*@ 
<input type="hidden" id="count" value="@(Model.Orders.Count()-1)">


<script type="text/javascript">

    $("#AddOrder").on('click', function (e) {

        //get the counter input and store it because we're going to update the value later.
        var counterInput = $("#count");
        var counter = counterInput.val();
        counter++;
        //Assumed your new order description has an id of description.
        var description = $("#description").val();
        //Again you need to prepare your html so that the model binding will work by forming the name correctly.
        var newRow = "<tr><td><input type='hidden' name='Orders[" + counter + "].OrderId' value='0' /></td><td <input type='hidden' name='Orders[" + counter + "].OrderDesc value=" + description +" /></td></tr>";
        var tableBody = $("#tableBody");
        //Append the new tr to the table body after the other rows (might be a better way to do this with append or something similar).
        tableBody[0].innerHTML = tableBody[0].innerHTML + newRow;

        //Update the counter stored in the input so that we can keep track of how many items we have in the list to try avoid duplicate numbers
        counterInput.val(counter);
    });

    $(".removeOrderBtn").on('click', function (e) {
        var id = e.target.dataset.id;

        var tableBody = $("#tableBody");
        tableBody.remove("#Order-" + id); // I think this takes a selector.
        var counterInput = $("#count");
        var counter = counterInput.val();
        counter--;
        counterInput.val(counter);

    });

</script>

Дайте мне знать, если у вас есть какие-либо вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...