Созданный элемент нельзя редактировать или удалить без обновления сетки в ShieldUI.

Я хочу использовать библиотеку ShieldUI (компонент сетки) для представления пользователю табличных данных.
Проблема с этой библиотекой заключается в том, что если я создаю новый элемент и сразу после того, как хочу его отредактировать или удалить, сетка не может предоставить свой идентификатор (поскольку база данных генерирует для меня), хотя я возвращаю идентификатор из бэкэнда после выполнения запроса INSERT. Вот что я пробовал:

<!-- HTML and JS part -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>jQuery Shield UI Demos</title>
    <link id="themecss" rel="stylesheet" type="text/css" href="//www.shieldui.com/shared/components/latest/css/light/all.min.css" />
    <script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/jquery-1.11.1.min.js"></script>
    <script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/shieldui-all.min.js"></script>
</head>
<body class="theme-light">
<div id="grid"></div>
<script type="text/javascript">
    $(document).ready(function () {
        $("#grid").shieldGrid({
            dataSource: {
                remote: {
                    read: "/products",
                    modify: {
                        create: {
                            url: "/products/productCreate",
                            type: "post",
                            data: function (edited) {
                                var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
                                return {
                                    Active: edited[0].data.Active,
                                    AddedOn: date,
                                    Category: edited[0].data.Category,
                                    Name: edited[0].data.Name,
                                    Price: edited[0].data.Price,
                                    Id: edited[0].data.Id
                                };
                            }
                        },
                        update: {
                            url: "/products/productUpdate",
                            type: "post",
                            data: function (edited) {
                                var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
                                return { 
                                    Active: edited[0].data.Active,
                                    AddedOn: date,
                                    Category: edited[0].data.Category,
                                    Name: edited[0].data.Name,
                                    Price: edited[0].data.Price,
                                    Id: edited[0].data.Id
                                };
                            }
                        },
                        remove: {
                            url: "/products/productRemove",
                            type: "post",
                            data: function (removed) {
                                return { id: removed[0].data.Id };
                            }
                        }
                    }
                },
                schema: {
                    fields: {
                        Id: { path: "Id", type: Number },
                        Price: { path: "Price", type: Number },
                        Name: { path: "Name", type: String },
                        Category: { path: "Category", type: String },
                        AddedOn: { path: "AddedOn", type: Date },
                        Active: { path: "Active", type: Boolean }
                    }
                }
            },
            rowHover: false,
            columns: [
                { field: "Name", title: "Product Name", width: "300px" },
                { field: "Price", title: "Price", width: "100px" },
                { field: "Category", title: "Category", width: "200px" },
                { field: "AddedOn", title: "Added On", format: "{0:MM/dd/yyyy}" },
                { field: "Active", title: "Active" },
                {
                    title: " ",
                    width: "100px",
                    buttons: [
                        { cls: "deleteButton", commandName: "delete", caption: "<img src='/Content/img/grid/delete.png' /><span>Delete</span>" }
                    ]
                }
            ],
            editing: {
                enabled: true,
                event: "click",
                type: "cell",
                confirmation: {
                    "delete": {
                        enabled: true,
                        template: function (item) {
                            return "Delete row with ID = " + item.Id
                        }
                    }
                }
            },
            toolbar: [
                {
                    buttons: [
                        { commandName: "insert", caption: "Add Product" }
                    ],
                    position: "top"
                }
            ]
        });
    });
</script>
<style>
    .deleteButton img
    {
        margin-right: 3px;
        vertical-align: bottom;
    }
</style>
</body>
</html>

Ниже приведена часть ASP.MVC:

[ActionName("productCreate")]
public Product PostProduct(Product item)
{
    if (item == null)
    {
         throw new ArgumentNullException("item");
    }
    item.Id = Products.Max(i => i.Id) + 1;
    Products.Add(item);
    return item;
}

Чтобы это работало, мне нужно обновить содержимое сетки, выполнив операцию сортировки (платформа обновляет сетку перед сортировкой) или, что еще хуже, обновление страницы.
Так в чем проблема с этим подходом? Я что-то упускаю?


person Dani Grosu    schedule 24.10.2018    source источник
comment
Можете ли вы предоставить пример JSBin, который использует ваш веб-сервис и воспроизводит проблему?   -  person Vladimir Georgiev    schedule 25.10.2018
comment
А тем временем вы можете использовать функцию modify.create для обработки создания и передачи идентификатора данным, как показано в этом примере: demos.shieldui.com/web/grid-editing/editing-restful-web-service   -  person Vladimir Georgiev    schedule 25.10.2018
comment
Спасибо, что привели меня к примеру спокойного веб-сервиса. Используя вызов AJAX и обновляя идентификатор вновь созданного элемента, он работает нормально. Я думал, что библиотека сделает это за меня.   -  person Dani Grosu    schedule 26.10.2018


Ответы (1)


Нам нужно изменить объект create и использовать вызов AJAX, чтобы все заработало.
Итак, вместо:

create: {
    url: "/products/productCreate",
    type: "post",
    data: function (edited) {
        var date = edited[0].data.AddedOn ? edited[0].data.AddedOn.toJSON() : new Date().toJSON();
        return {
            Active: edited[0].data.Active,
            AddedOn: date,
            Category: edited[0].data.Category,
            Name: edited[0].data.Name,
            Price: edited[0].data.Price,
            Id: edited[0].data.Id
        };
    }
}

Ты должен сделать:

create: function (items, success, error) {
    var newItem = items[0];
    $.ajax({
        type: "POST",
        url: "/products/productCreate",
        dataType: "json",
        data: newItem.data,
        complete: function (xhr) {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    // update the id of the newly-created item with the 
                    // one returned from the server
                    newItem.data.Id = xhr.responseJSON.Id;
                    success();
                    return;
                }
            }
            error(xhr);
        }
    });
}
person Dani Grosu    schedule 26.10.2018