【问题标题】:refresh table without refreshing page刷新表格而不刷新页面
【发布时间】:2016-04-23 18:36:17
【问题描述】:

我有一个使用 knockoutjs 显示数组内容的表格。我希望能够通过单击列的标题来对该表进行排序。我的想法是使用javascript .sort() 对数组进行排序,然后刷新表格而不刷新页面。我不知道如何在不刷新页面的情况下刷新表格。如果有人能指出我正确的方向,将不胜感激!

现在它只是一个 html 表格。一些单元格包含 if 语句,其他单元格包含整个表格,并且数据库中有超过 80 条记录。我不想再做一个ajax调用,因为数据库中没有任何变化,只想根据点击的标题对数组进行排序。

我添加了 onclick 函数,但我得到了 obj 未定义的错误。

下面是简化版的代码:

aspx 文件:

<table id="filteredTable">
    <tr>
        <th><button class="btn btn-link btn sm" onclick="SortColumn('TicketTitle')">Title</button></th>
        <th>Priority</th>
    </tr>
<tbody data-bind="foreach: theObject[0]">
    <tr class="tableRow" data-bind="attr: { id: TicketId }">
        <td data-bind="text: TicketTitle"></td>
        <td data-bind="text: TicketPriority"></td>
    </tr>
</tbody>
</table>

js 文件:

function pageLoad() {
    var url = API_URL + "/api/Ticket/GetTickets";
    var data = Ajax.getData(url);
    var obj = [];
    var tickets = JSON.parse(data.JsonResult);
    obj.Tickets = tickets;
    Tickets.Data = obj;

    var viewModel = {
        theObject: [obj.Tickets]
    };

    ko.applyBindings(viewModel);
}

function SortColumn(column) {
    obj.Tickets.column.sort();
}

【问题讨论】:

  • 您使用的是数据表还是简单的 html 表。如果您可以使用数据表并且您可以使用 fnDraw() 为您重新绘制表格
  • 如果您向我们提供代码,也许对您有一点帮助

标签: javascript html knockout.js


【解决方案1】:

我的回答将与this earlier answer 非常相似,建议使用计算出的 observable 来表示排序表。对于您的场景,它可能如下所示:

function ViewModel(obj) {
  var self = this;
  
  self.Tickets = ko.observableArray(obj.Tickets);
  
  self.sortKey = ko.observable("TicketTitle");
  
  self.changeSort = function(newKey) {
    // TODO: Handle asc/desc here too.
    self.sortKey(newKey);
  };
  
  self.TicketsSorted = ko.computed(function() {
    var key = self.sortKey();
    return self.Tickets().sort(function(a, b) {
      return a[key].localeCompare(b[key]);
    });
  });
}

function pageLoad() {
  // Fake data:
  var obj = { Tickets: [
    { TicketId: 1, TicketTitle: "Aaa title", TicketPriority: "C. Low" },
    { TicketId: 2, TicketTitle: "Be a title", TicketPriority: "B. Medium" },
    { TicketId: 3, TicketTitle: "Aaa title", TicketPriority: "A. High" },
    { TicketId: 4, TicketTitle: "Baahaha ya", TicketPriority: "A. High" },
    { TicketId: 5, TicketTitle: "C u later", TicketPriority: "B. Medium" }
  ] };

  var viewModel = new ViewModel(obj);

  ko.applyBindings(viewModel);
}

pageLoad();
td { padding: 2px 5px; background: #eee; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<table>
  <tr>
    <th>
      <button data-bind="click: changeSort('TicketTitle')">Title</button>
    </th>
    <th>
      <button data-bind="click: changeSort('TicketPriority')">Priority</button>
    </th>
  </tr>
  <tbody data-bind="foreach: TicketsSorted">
    <tr class="tableRow" data-bind="attr: { id: TicketId }">
      <td data-bind="text: TicketTitle"></td>
      <td data-bind="text: TicketPriority"></td>
    </tr>
  </tbody>
</table>

不知道如何在您的帖子中存根丢失的位(例如数据以及如何检索它),所以我只是在那里插入了一些普通数据。 (PS。看起来您的 Ajax 调用是同步处理的?)

【讨论】:

  • 我想试试这个,但不知道在 TODO 部分放什么。我希望它按字母顺序对标题进行排序。
  • 除了 TODO 与您的特定问题并不直接相关之外,如果您甚至不知道从哪里开始该 TODO,我建议您阅读一些教程,例如the ko tutorials are great,一旦遇到特定问题,就会重新开始。
  • (虽然我现在看到 @SebastiánRodriguez cut out some of the work for you 通过将我的代码示例与一些排序顺序魔术重新混合。)
【解决方案2】:

如果您的表格显示了数组的元素(使用淘汰赛的 foreach 函数),您不能刷新表格...

对数组进行排序会对表格进行排序...

但是,如果你想简化你的生活,我建议使用DataTables plugin

使用此插件,您只需在 DOM 中绘制表格,然后将数据表应用于您绘制的表格...


希望对您有所帮助。

问候


编辑:

试试这个(基于@Jeroen solution):

HTML:

<table>
    <tr>
        <th>
            <!-- Calling a unnamed function to prevent auto-execute of the function 'changeSort' on binding -->
            <button data-bind="click: function() { resetDir('TicketTitle'); changeSort('TicketTitle'); }">Title</button>
        </th>
        <th>
            <!-- Calling a unnamed function to prevent auto-execute of the function 'changeSort' on binding -->
            <button data-bind="click: function() { resetDir('TicketPriority'); changeSort('TicketPriority'); }">Priority</button>
        </th>
    </tr>
    <tbody data-bind="foreach: Tickets">
        <tr class="tableRow" data-bind="attr: { id: TicketId }">
            <td data-bind="text: TicketTitle"></td>
            <td data-bind="text: TicketPriority"></td>
        </tr>
    </tbody>
</table>

Javascript:

function ViewModel(obj) {
    var self = this;

    var sortDir = {
        TicketTitle: "DESC",
        TicketPriority: "DESC",
        LastPressed: ""
    };

    self.Tickets = ko.observableArray(obj.Tickets);

    self.resetDir = function(key) {
        if(sortDir['LastPressed'] != key) sortDir[key] = "DESC";
    }

    self.changeSort = function(newKey) {
        if(sortDir[newKey] == "ASC") sortDir[newKey] = "DESC";
        else sortDir[newKey] = "ASC";

        self.Tickets.sort(function(a, b) {
            if(sortDir[newKey] == "ASC") {
                if(a[newKey] < b[newKey]) return -1;
                if(a[newKey] > b[newKey]) return 1;
                return 0;
            } else {
                if(b[newKey] < a[newKey]) return -1;
                if(b[newKey] > a[newKey]) return 1;
                return 0;
            }
        });

        sortDir['LastPressed'] = newKey;
    };

    self.changeSort("TicketTitle");
}

function pageLoad() {
    // Fake data:
    var obj = {
        Tickets: [
            { TicketId: 1, TicketTitle: "Aaa title", TicketPriority: "C. Low" },
            { TicketId: 2, TicketTitle: "Be a title", TicketPriority: "B. Medium" },
            { TicketId: 3, TicketTitle: "Aaa title", TicketPriority: "A. High" },
            { TicketId: 4, TicketTitle: "Baahaha ya", TicketPriority: "A. High" },
            { TicketId: 5, TicketTitle: "C u later", TicketPriority: "B. Medium" }
        ]
    };

    var viewModel = new ViewModel(obj);

    ko.applyBindings(viewModel);
}

pageLoad();

测试JSFiddle中的代码

【讨论】:

  • 哇,我想你可能是对的,这就是淘汰赛的工作方式。我现在就试试。
  • 我收到一个错误,因为我不知道如何将数组传递给我的 SortColumn 函数
  • 您不能将数组作为函数参数传递...您只需对创建的数组进行排序即可填充表格...
  • 上面的编辑:你不能将你的数组作为函数参数传递......你只需要对你创建的数组进行排序以填充表格......假设你的数组被命名为@ 987654326@,您应该在 SortColumn 函数中执行 theObject.sort()。也许你应该像这样引用数组:this.theObject.sort()
  • 通过将数组置于全局范围内解决了错误。但是,当我单击表头时,该功能不起作用。数组中的元素顺序不同,但它们不是按字母顺序排列的。并且表格中的行顺序完全没有改变。
【解决方案3】:

在我看来你可以做这样的事情......但是

function refresh(){
var cont = "<table>"+
    "<tr>"+/*use  loop */
      "<td>"+
        "name"+
      "</td>"+
      "<td>"+
        "exe"+
      "</td>"+
    "</tr>"+
    "<tr>"+
      "<td>"+
        "name2"+
      "<td>"+
        "exe2"+
      "</td>"+
      "</td>"+
    "</tr>"+
   "</table>";
  return cont;
}
document.getElementById("tableContainerID").innerHTML = refresh();
&lt;div id="tableContainerID"&gt;&lt;/div&gt;

你可以创建一个函数,然后给你所有的表数据,然后像这样调用函数:document.getElementById("tableContainerID").innerHTML = TableDataFunction();

如果您使用 jquery,那么也许这可以帮助您.html();

【讨论】:

    猜你喜欢
    • 2014-01-10
    • 2011-12-22
    • 1970-01-01
    • 2011-04-28
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    相关资源
    最近更新 更多