【问题标题】:How do I capture only those columns in multiple rows in which user has changed values?如何仅捕获用户更改值的多行中的那些列?
【发布时间】:2019-12-16 05:55:06
【问题描述】:

在 ASP.NET 或 JavaScript 中是否有任何方法,我只对用户更新了特定列的行运行更新存储过程?

例如:如果有多行

row1= [column1 column2 column3 column4 coumn 5]
row2= [column1 column2 column3 column4 coumn 5]
row3= [column1 column2 column3 column4 coumn 5]
row4= [column1 column2 column3 column4 coumn 5]

如果第 1 行中更新了第 2 列和第 3 列,并且第 3 行中更新了第 1 列和第 4 列,我只想捕获这些行和列并将其作为 JSON 字符串传递给 List,然后我将其转换为 DataTable ?

我应该采取什么方法?

我尝试过的:

谷歌搜索了一些样本,但专家意见总是最好的

【问题讨论】:

    标签: javascript asp.net-mvc model-view-controller


    【解决方案1】:

    有一种非常复杂的方法可以实现这一点。如果有人知道更清洁的方法,张贴。

    您需要执行以下操作:

    添加到您的模型: - 一个布尔属性(列),将被隐藏并用作更改标识符

    像这样在你的视图中设置你的表(我的例子是在 Razor 中):

    @{
    int j = 1;
    for (var i = 0; i < Model.itemList.Count; i++)
    {
         <tr>
              <td>
                   @Html.TextBoxFor(model => model.itemList[i].columnOne, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
              </td>
              <td>
                   @Html.TextBoxFor(model => model.itemList[i].columnTwo, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
              </td>
              <td>
                   @Html.TextBoxFor(model => model.itemList[i].columnThree, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
              </td>
              <td>
                   @Html.TextBoxFor(model => model.itemList[i].columnFour, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
              </td>
              <td>
                   @Html.TextBoxFor(model => model.itemList[i].columnFive, new { onkeypress = "markAsChanged(" + @j + ", " + @i + ")" })
              </td>
              <td>
                   @Html.HiddenFor(model => model.itemList[i].IsChanged)
              </td>
         </tr>
         j++;
    }
    

    一旦有人更改了一行的字段,您的 JavaScript 函数就会编辑隐藏元素:

    function rerunOldChange(rowIndex, changeIndex) {
        var table = document.getElementById("changeTable");
        var j = rowIndex;
        var i = changeIndex;
    
        var currentRow = table.rows[j];
        var cellSix = currentRow.cells[5];
    
        var thisRowIsChanged = "<input type = 'hidden' id = 'itemList_" + i + "__IsChanged' name = 'itemList[" + i + "].IsChanged' value = 'true' />"
    
        cellSix.innerHTML = thisRowIsChanged;
    }
    

    它所做的是在有人按下该字段上的键时立即更改布尔值。因此,当您将列表传递给控制器​​以进行发布时,您只能对布尔值为 True 的行执行此操作。

    【讨论】:

      【解决方案2】:

      我将对@C Murphy 的回复进行一些更新和简化,但在您的视图模型中设置隐藏字段是最佳选择。我建议使用复选框,因为它默认为布尔值,并且易于使用其checked 属性进行操作。

      keypress event is deprecated,并且不会在所有键上触发 - 特别是 BackspaceDelete 键不会触发它,因此有人可以删除其中的所有内容一个字段,不会发生更新。相反,使用keydown 事件;这有点 相反 效果,因为每个键都会触发它,包括 Shift 和其他可能不会实际更改字段的键。如果需要,您可以验证其他代码中的更改。

      我删除了检查每列更改的代码,因为我假设您的更新逻辑要求所有对象的数据,或者使用 EF 可能希望传递整个对象。

      剃须刀:

      // A text field, change PropertyName and add where needed in markup
      @Html.TextBoxFor(model => model.itemList[i].PropertyName, new { onkeydown = "markAsChanged(" + i + ")" })
      
      // Hidden checkbox for the IsChanged property
      @Html.CheckBoxFor(model => model.itemList[i].PropertyName, new { hidden = "" })
      

      Javascript:

      // Modern browsers
      var markAsChanged = function(i) {
          document.GetElementById('itemList_' + i + '__IsChanged').checked = true;
      };
      
      // Use for legacy support with jQuery
      var markAsChanged = function(i) {
          $('#itemList_' + i + '__IsChanged').checked = true;
      };
      

      如果您想清理视图并省略事件处理程序,可以使用更多 Javascript 添加它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-25
        • 2017-05-13
        • 1970-01-01
        • 1970-01-01
        • 2018-08-07
        • 2020-05-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多