Использование JavaScript для вызова функции контроллера в проекте MVC - PullRequest
3 голосов
/ 10 июня 2019

Я работаю над базовым проектом MVC ASP.NET с EF 6, который хранит данные о продукте в базе данных и создает список обработки и доставки.Важной особенностью проекта является то, что некоторые пользователи могут изменять порядок этого списка вручную, что я реализую с помощью перетаскивания карт.Каждая карта создается путем циклического перебора IEnumerable модели в представлении, где каждая

содержит часть, которая отображает карту.У меня проблема в том, что изменение порядка в представлении по сути не меняет атрибут Product.Order в проекте.Мне нужен способ получить доступ к элементу модели перемещаемой карты и элементу модели. Заказ карты узурпирован внутри имеющейся у меня функции сброса JavaScript.

В настоящее время я пытаюсь использовать var order = @Html.Raw (JsonConvert.SerializeObject (item.Order) as String); но, похоже, это не подвергает JavaScript воздействию, с которым я могу работать.У меня есть вторая строка, отображающая весь объект.

Метод контроллера:

public void ChangeOrder(Product p, int order)
        {

            //This creates a list of all of the jobs in the database sorted by descending Order
            var PList = from prod in _context.Products select prod;
            PList = PList.OrderByDescending(prod => prod.Order);

            int origin = p.Order;
            p.Order = order;

            if(origin > order)
            {
                int it = order;
                while (it < origin && it < PList.Count())
                {
                    PList.ElementAt(it++).Order--;
                }
            } else if(origin < order)
            {
                int it = origin;
                while (it < order && it < PList.Count())
                {
                    PList.ElementAt(it++).Order--;
                }
            } else
            {
                return;
            }
        }

Индексный просмотр

@using Newtonsoft.Json;
@model IEnumerable<Project.Models.Product>


@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

@*The list container*@
<ul class="container" id="dragfield" style="width: 100%;">
    @*The first card is a minicontainer for the create partial view*@
    <li class="card popupsrc" onclick="callPopup">...</li>
    @foreach (var item in Model)
    {
        <li class="dragcard" draggable="true" style="float: left; padding: 8px">@item.Order @*For debugging purposes, this displays the order with the card*@
            @*THE FOLLOWING LINEs ARE NOT SECURED AND SHOULD BE CHANGED BEFORE PUBLISHING - FOR TESTING PURPOSES ONLY*@
            var order = @Html.Raw(JsonConvert.SerializeObject(item.Order) as String);
            var order = @Html.Raw(JsonConvert.SerializeObject(item) as String);
            <partial name="_ProductCard.cshtml" model="item" />
        </li>
    }
</ul>

site.js Блок перетаскивания

//D&D Functions Start
{
    var dragSrcElem = null;

    function dragStartHandler(event)
    {
        // Target (this) element is card being dragged.
        dragSrcElem = this;

        event.dataTransfer.effectAllowed = 'move';
        event.dataTransfer.setData('text/html', this.outerHTML);

        this.classList.add('dragElem');
    }
    function dragOverHandler(event)
    {
        if (event.preventDefault)
        {
            event.preventDefault(); //Enables dropping
        }
        this.classList.add('over');

        event.dataTransfer.dropEffect = 'move';

        return false;
    }

    function dragEnterHandler(event) {
        // this|event.target is the card being hovered over.
    }

    function dragLeaveHandler(event) {
        this.classList.remove('over');  // this|e.target is card previously hovered over.
    }

    function handleDrop(event) {
        // this/e.target is card about to be usurped.

        if (event.stopPropagation) {
            event.stopPropagation(); // Prevents browsers from redirecting and cancelling the drag&drop 
        }

        // If the card hasn't moved, do nothing
        if (dragSrcElem != this) {
            // Set the original card's HTML to the HTML of the card we dropped on
            this.parentNode.removeChild(dragSrcElem);
            var dropHTML = event.dataTransfer.getData('text/html');
            this.insertAdjacentHTML('beforebegin', dropHTML);
            //refocuses to the original card
            var dropElem = this.previousSibling;

//LOCATION OF ISSUE
            //call the Controller function to change the Order Attribute of the relocated card's item
            PFS.Controllers.ChangeOrder(dropElem, this.order);
//LOCATION OF ISSUE

            addDnDHandlers(dropElem);

        }
        this.classList.remove('over');
        return false;
    }

    function dragEndHandler(event) {
        // this|e.target is the original card.
        this.classList.remove('over');
    }

    function addDnDHandlers(elem) {
        elem.addEventListener('dragstart', dragStartHandler, false);
        elem.addEventListener('dragenter', dragEnterHandler, false)
        elem.addEventListener('dragover', dragOverHandler, false);
        elem.addEventListener('dragleave', dragLeaveHandler, false);
        elem.addEventListener('drop', dropHandler, false);
        elem.addEventListener('dragend', dragEndHandler, false);

    }

    var jc = document.querySelectorAll('#dragcard .dragcard');
    [].forEach.call(jc, addDnDHandlers);
}
//D&D Functions End

Я ожидаю, что функция handleDrop JavaScript вызовет функцию в контроллере, используя параметры из представления, которое первоначально вызывало функцию JS.В настоящее время код, который я реализовал в представлении, не предоставляет необходимую информацию для кода Javascript таким образом, который я знаю, как получить к нему доступ, и при этом JS не распознает функцию Controller

1 Ответ

0 голосов
/ 10 июня 2019

Из вашего кода JavaScript я не уверен, что именно PFS находится в контексте PFS.Controllers.ChangeOrder..., поэтому я не уверен, что смогу там помочь.

Лично, когда я пытаюсь связатьсядействие контроллера, мне нравится встроенная функция JavaScript fetch.По сути, вы передаете URL в качестве параметра и объекта, если хотите указать какие-либо другие детали (например, тело или что-то еще).Это выглядит примерно так:

//Of course you should replace this with your actual url, this one is just for demo //purposes.
const changeOrderUrl = "order/ChangeOrder"; 

fetch(changeOrderUrl, {
    method: "POST", //or GET or whatever your controller action is
    body: JSON.stringify({
        p: dropElem,
        order: this.order
    }),
    headers: { "content-type": "application/json; charset=utf-8" }
})
.then(response => response.json())
.then((responseData) => {
    //Do whatever you want with the response here. IF you don't want to do anything with 
    //the response, you can remove both of the .then()'s
});

Кроме того, вам, скорее всего, придется добавить атрибут [FromBody] к параметрам действия контроллера, например: public void ChangeOrder([FromBody]Product p, int order)

Дайте мне знатьесли я могу помочь любым другим способом!

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