javascript - 根据 id 切换 MVC 表行的可见性

标签 javascript ajax toggle row visibility

在我的 MVC Razor View 中,我有一个表,其中的行代表层次结构的两个级别。可以通过 ajax 调用单击每一行来加载部分 View 内容区域。这工作得很好。

为了获得更紧凑的列表,我现在想将表格变成“轻型可折叠 TreeView ”。仅当单击标题行时,第二级中的行才应可见。单击另一个标题行时,所有当前子行应折叠/隐藏,并展开新的子行集。

我主要是一个代码隐藏人员,不太习惯客户端脚本编写。我尝试了多种方法,但到目前为止还没有成功。我读过一些建议,但它们都略有不同,并且不能直接适用。这是我目前的尝试:

<table style="width: 100%;">
    <tr>
        <td style="width: 30%; vertical-align: top;">
            <table id="myTableTree" style="width: 100%;">
                @foreach (var testSuite in Model.TestSuites)
                {
                    <tr>
                        <th colspan="2" style="text-align: left;">
                            @Ajax.ActionLink(testSuite.Description, "GetContent", new { testSuiteId = testSuite.Id }, new AjaxOptions { UpdateTargetId = "subContent" }, new { onClick = "setShowState(" + testSuite.Id + ");" })
                        </th>
                    </tr>
                    foreach (var testCase in testSuite.TestCases)
                    {
                    <tr itemprop="@testSuite.Id" style="display: none;">
                        <td>&nbsp;</td>
                        <td>
                            @Ajax.ActionLink(testCase.Description, "GetContent", new { testCaseId = testCase.Id }, new AjaxOptions { UpdateTargetId = "subContent" })
                        </td>
                    </tr>
                    }
                }
            </table>
        </td>
        <td style="vertical-align: top;" id="subContent"></td>
    </tr>
</table>

<script type="text/javascript">
    function setShowState (testSuiteId)
    {
        var rows = document.getElementById('myTableTree').rows;
        for (var i = 0; i < rows.length; i++)
        {
            var row = rows.item(i);
            if (row.attributes['itemprop'] == testSuiteId)
                row.style.display = 'block';
            else
                row.style.display = 'none';
        }
    };
</script>

如您所见,所有子行最初都设置为 display=none。我获取了一个任意属性来保存每个第二级行上的第一级 id。 itemprop 似乎和其他的一样好。在第一级行中,我添加了一个引用 JavaScript 函数的 onClick 调用。 setShowState 函数的目的是循环所有行并为行设置适当的可见性。当我检查生成的页面源时,它看起来像我预期的那样,但不起作用。子行永远不会扩展。

1) 设置初始服务器返回行 display=none 然后在客户端切换是否可以?

2) 让actionlink 触发ajax 服务器调用并触发客户端脚本来设置可见性是否可以?或者将 ajax 调用移至 java 脚本以仅进行一次调用会更好吗?

3) 使用display=block/none 或visibility=visible/collapse 进行切换是否更好?实际上会有什么区别吗?

4) 使用 itemprop 来存储父 id 可以吗?我看到许多人在类似的情况下使用类属性。类属性可以与纯整数值一起使用吗?

5)按照我想要的方式切换行的最快方法是什么?循环所有行是否太慢?我将有 10-20 个标题行,每行有 2-10 个子行。

6) 整个设计很糟糕吗?我在 MVC 工具箱中没有找到 TreeView 控件,因此我决定采用这种方式。我认为这看起来至少和 TreeView 一样漂亮,但也许另一种方法会更好?

7) jQuery 有什么帮助吗?我的布局页面中包含 jQuery 库,但我不知道如何使用它。

最佳答案

与之前很多次一样,表达一个详细的问题是非常清晰的。经过更多检查后,我意识到我只是错过了解析属性的语法。此示例现已完全运行:

<table style="width: 100%;">
    <tr>
        <td style="width: 30%; vertical-align: top;">
            <table id="myTableTree" style="width: 100%;">
                @foreach (var testSuite in Model.TestSuites)
                {
                    <tr>
                        <th colspan="2" style="text-align: left; border: 0;">
                            @Ajax.ActionLink(testSuite.Description, "GetContent", new { testSuiteId = testSuite.Id }, new AjaxOptions { UpdateTargetId = "subContent" }, new { onClick = "setShowState(" + testSuite.Id + ");" })
                        </th>
                    </tr>
                    foreach (var testCase in testSuite.TestCases)
                    {
                    <tr data-testSuiteId="@testSuite.Id" style="visibility: collapse;">
                        <td style="width: 10%; border: 0;">&nbsp;</td>
                        <td style="border: 0;">
                            @Ajax.ActionLink(testCase.Description, "GetContent", new { testCaseId = testCase.Id }, new AjaxOptions { UpdateTargetId = "subContent" })
                        </td>
                    </tr>
                    }
                }
            </table>
        </td>
        <td style="vertical-align: top;" id="subContent"></td>
    </tr>
</table>

<script type="text/javascript">

    // Toggle each section independantly
    function setShowState(testSuiteId) {
        var rows = document.querySelectorAll('[data-testSuiteId="' + testSuiteId + '"]');
        for (var i = 0; i < rows.length; i++) {
            var row = rows.item(i);
            row.style.visibility = (row.style.visibility == 'visible') ? 'collapse' : 'visible';
        }
    };

    // Alternative algorithm
    // Always collapse previous section when a new one is selected
    function setShowState2(testSuiteId) {
        var rows = document.getElementById('myTableTree').rows;
        for (var i = 0; i < rows.length; i++) {
            var row = rows.item(i);
            if (row.getAttribute('data-testSuiteId') == testSuiteId)
                row.style.visibility = 'visible';
            else if (row.getAttribute('data-testSuiteId') != null)
                row.style.visibility = 'collapse';
        }
    };
</script>

我对我自己的问题提出以下建议:

1)是的,设置属性然后在客户端切换是完全可以的。

2) 是的,触发一个服务器端操作并同时触发一个客户端似乎没问题。

3)我试过了。就我而言,它似乎在显示和可见性方面都工作得同样好。通过进一步阅读,我了解到大多数情况下都会使用显示,但表格中的可见性稍好一些,因为不需要重新计算大小等表格属性。

4) itemprop 属性有效。但在 HTML5 中建议使用 data 属性。所以我用“data-testSuiteId”交换了“itemprop”。

5)可能有更快的方法,但这看起来对我来说可以接受。

6) 替代控制?

7) 使用 jQuery 也可以完成同样的任务。这将使代码更加紧凑,实际上也更快。

// Toggle section
function setShowState(testSuiteId) {
    $("[data-testSuiteId='" + testSuiteId + "']").toggle();
};

// Display one section and collapse all others
function setShowState(testSuiteId) {
    $("[data-testSuiteId]").hide();
    $("[data-testSuiteId='" + testSuiteId + "']").show();
};

关于javascript - 根据 id 切换 MVC 表行的可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17125381/

相关文章:

javascript - 如何每隔5秒连续调用一次JS函数

jquery - 切换类(class)效果不佳

javascript在点击时启用禁用复选框并一次只选择一个

php - 如何在php中编写html代码?

javascript - 使用 Javascript 函数在背景颜色之上添加背景图像

javascript - 扩展视频播放器,例如 CNN 网站,最好基于 jQuery

javascript - 切换脚本和不起作用的按钮

javascript - Javascript 中的连续工作日(无周末)

javascript - 视差/背景位置的特征检测

javascript - 对大多数请求使用 socket.io 是不好的还是我应该只使用它来将数据推送到客户端?