【问题标题】:Detect data change from different DOM element检测来自不同 DOM 元素的数据变化
【发布时间】:2017-06-13 07:14:53
【问题描述】:

TL;DR:从实际的<ul> 列表中检测项目变化并持久化数据

大家好?

我目前正在做一个基于 Trello 的 Web 应用程序,使用 PHP 作为后端,jQueryUI 作为前端。

前端部分使用sortable(),通过定义三个UL 元素。一个是 ID 为 Nav 的容器/包装器,另外两个是存放物品的实际板。

案例场景很简单:

  • 您可以重新排序板
  • 您可以在单板内移动项目的顺序
  • 您可以将项目从一个板移动到另一个板

包含的代码支持所有这三个,但数据应该保存到后端驱动的数据库(我目前在 SQLite 上,因为该项目处于早期阶段)。

问题

setSortAction 方法当前检测所有三个用例但是一旦您将项目从一个板移动到另一个板,就无法正确检测到列表的顺序(因为它们是递增值)。

像这样获取 bodyContentaction=updateMenuItemListings&record=2&record=1&record=3
通过将第二项移动到板中的第一个位置就可以了,我可以通过后端的 POST 请求将更改保存到数据库中。

当您将第一个项目从第二个板上移到第一个板上时会发生什么?您将获得类似于以下的 bodyContent 值: action=updateMenuItemListings&record=1&record=2&record=1&record=3

如您所见,值为 1 的记录重复。

这意味着我无法检测到移动的项目来自第二块板,并且我有重复的项目在板的顺序中。

你会如何设计这个?可以通过给定的代码来完成,还是我完全错过了在这种情况下应该应用的逻辑?

谢谢。

$(function() {

  var debugMode = true;

  $("ul.droptrue").sortable({
    connectWith: "ul"
  });

  //Set common sort settings for all lists
  $(".sortable").sortable({
    opacity: 0.6,
    cursor: 'move'
  });

  //Function used to configure update calls for each sort
  function setSortAction(selector, updatePage, updateAction, itemLabel) {
    $(selector).sortable({
      update: function() {
        var itemList = $(this).sortable(
          "serialize", {
            attribute: "id",
            key: itemLabel
          });

        //Create POST request to persist the update
        var bodyContent = "action=" + updateAction + "&" + itemList;
        if (debugMode) {
          alert("DEBUG: bodyContent = \n" + bodyContent);
        }

        //$.post(updatePage, bodyContent, function (postResult)
        //{ alert(postResult); });
      }
    });
  }

  //Set sort update action for top level and second level
  setSortAction(".navLevel1",
    "reorder.php",
    "updateMenuListings",
    "record");

  setSortAction(".navLevel2",
    "reorder.php",
    "updateMenuItemListings",
    "record");
});
@import url( 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css' );

#sortable_1,
#sortable_2,
#sortable_3 {
  list-style-type: none;
  margin: 0;
  float: left;
  margin-right: 10px;
  background: #eee;
  padding: 5px;
  width: 143px;
}

#sortable_1 li,
#sortable_2 li,
#sortable_3 li {
  margin: 5px;
  padding: 5px;
  font-size: 1.2em;
  width: 120px;
}

body {
  font-family: Arial, Helvetica, sans-serif;
}

table {
  font-size: 1em;
}

.ui-draggable,
.ui-droppable {
  background-position: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<ul id="Nav" class="sortable navLevel1">

  <ul id="sortable_1" class="droptrue navLevel2">

    <li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Classes</li>
    <li id="item_1" class="ui-state-default">Some class</li>
    <li id="item_2" class="ui-state-default">Another one!</li>
    <li id="item_3" class="ui-state-default">Yep, thats enough</li>

  </ul>

  <ul id="sortable_2" class="droptrue navLevel2">

    <li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Presentation</li>
    <li id="item_1" class="ui-state-default">Tom</li>
    <li id="item_2" class="ui-state-default">Jessica</li>
    <li id="item_3" class="ui-state-default">Kevin</li>

  </ul>
</ul>

<br style="clear:both">

【问题讨论】:

  • 首先你有非唯一的id,第二个表中的id最好从id="item_4"开始,依此类推。
  • 好的,有道理。实现了计数器,现在根据接收到的数据实现 id-s 增量。那么,您对存储设计有何建议?
  • 存储设计是指后端 SQLite 函数吗?如果是这样,这超出了我的职责范围,但是您可以使用每个表的大小作为从后端构建 html 时溢出的定义。
  • 非常感谢。

标签: javascript jquery html css jquery-ui


【解决方案1】:

与类不同,HTML ID 应该是唯一的,这样您就可以识别哪些项目来自哪些列。

例如,知道第一列有 4 个插槽,第二列有 6 个,这意味着 7、3、9、3、2、5、6、1、4、8、10 的请求数组被分成 4 个和6 因此

  1. 第一栏:7、3、9、10,
  2. 第二列:2、5、6、1、4、8

$(function() {

  var debugMode = true;

  $("ul.droptrue").sortable({
    connectWith: "ul"
  });

  //Set common sort settings for all lists
  $(".sortable").sortable({
    opacity: 0.6,
    cursor: 'move'
  });

  //Function used to configure update calls for each sort
  function setSortAction(selector, updatePage, updateAction, itemLabel) {
    $(selector).sortable({
      update: function() {
        var itemList = $(this).sortable(
          "serialize", {
            attribute: "id",
            key: itemLabel
          });

        //Create POST request to persist the update
        var bodyContent = "action=" + updateAction + "&" + itemList;
        if (debugMode) {
          $('#report').text("DEBUG: bodyContent = \n" + bodyContent);
        }

        //$.post(updatePage, bodyContent, function (postResult)
        //{ alert(postResult); });
      }
    });
  }

  //Set sort update action for top level and second level
  setSortAction(".navLevel1",
    "reorder.php",
    "updateMenuListings",
    "record");

  setSortAction(".navLevel2",
    "reorder.php",
    "updateMenuItemListings",
    "record");
});
@import url( 'https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css' );

#sortable_1,
#sortable_2,
#sortable_3 {
  list-style-type: none;
  margin: 0;
  float: left;
  margin-right: 10px;
  background: #eee;
  padding: 5px;
  width: 143px;
}

#sortable_1 li,
#sortable_2 li,
#sortable_3 li {
  margin: 5px;
  padding: 5px;
  font-size: 1.2em;
  width: 120px;
}

body {
  font-family: Arial, Helvetica, sans-serif;
}

table {
  font-size: 1em;
}

.ui-draggable,
.ui-droppable {
  background-position: top;
}

#report {
 position: fixed;
 font-size: 0.5em;
 bottom: 2em;
 left: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<ul id="Nav" class="sortable navLevel1">

  <ul id="sortable_1" class="droptrue navLevel2">

    <li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Classes</li>
    <li id="item_1" class="ui-state-default">Some class</li>
    <li id="item_2" class="ui-state-default">Another one!</li>
    <li id="item_3" class="ui-state-default">Yep, thats enough</li>

  </ul>

  <ul id="sortable_2" class="droptrue navLevel2">

    <li class="ui-state-disabled" style="opacity: 1; pointers-event: none; background: yellow">Presentation</li>
    <li id="item_4" class="ui-state-default">Tom</li>
    <li id="item_5" class="ui-state-default">Jessica</li>
    <li id="item_6" class="ui-state-default">Kevin</li>

  </ul>
</ul>

<div id="report"></div>
<br style="clear:both">

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 2021-06-07
    相关资源
    最近更新 更多