2015-02-09 51 views
0

我正在開發一個遠程監視應用程序,並且遇到了一個問題,我希望看看能否獲得有關如何最佳解決問題的一些想法。實時應用程序中基於會話的DOM對象可見性操作

當服務器確定數據庫中有新信息顯示給客戶端時,它調用請求新局部視圖的SignalR客戶端方法。

在主頁上,我有一個簡單的JQuery腳本,用於切換表的可見性以及部分視圖中包含的子行。

現在的問題應該是顯而易見的。當AJAX用新返回的局部視圖更新DOM時,局部視圖中的對象將返回到其初始默認可見性狀態。這是完全預期的,但是我想讓每個元素的可見性狀態在整個連接的客戶端會話中保持不變。

在局部視圖中的數據基本上保持不變(不真正需要擔心的表和或行被添加或儘可能正常的實時操作而言刪除。)

守則:

JQuery的控制:(不優化,但工作)

$("#systemDetails").on("click", "#deviceDetail", function() { 
    if ($(this).closest('tr').next().is(':hidden')) { 
     $("[id^=child]").hide(); 
     $("[id^=deviceDetail]").removeClass('glyphicon-minus-sign'); 
     $("[id^=deviceDetail]").addClass('glyphicon-plus-sign'); 
     $(this).closest('tr').next().toggle("slow"); 
     $(this).toggleClass("glyphicon-plus-sign glyphicon-minus-sign"); 
    } 
    else { 
     $("[id^=child]").hide(); 
     $(this).toggleClass("glyphicon-plus-sign glyphicon-minus-sign"); 
    } 
}); 

$("#systemDetails").on("click", "#categoryToggle", function() { 
    $(this).closest('table').next().toggle("slow"); 
    $(this).toggleClass("glyphicon-plus-sign glyphicon-minus-sign"); 
}); 

主視圖:

@model xxxx.Models.SystemModel 

@{ 
    ViewBag.Title = "System Details"; 
} 

<div class="row"> 
    <div class="col-md-12"> 
     <div id="systemDetails"> 
      @Html.Action("GetDetails", "Monitoring", Model.Customer.SONumber) 
     </div> 
    </div> 
</div> 

@section Scripts{ 
    <script src="/Scripts/systemdetails.js"></script> 
    <script src="/Scripts/jquery.signalR-2.1.2.js"></script> 
    <!--Reference the autogenerated SignalR hub script. --> 
    <script src="/signalr/hubs"></script> 
    <script type="text/javascript"> 
    $(function() { 
     // Declare a proxy to reference the hub. 
     var notifications = $.connection.monitoringHub; 

     //debugger; 
     // Create a function that the hub can call to broadcast messages. 
     notifications.client.updateDetails = function (sonumber) { 
      getDetails(sonumber) 
     }; 
     // Start the connection. 
     $.connection.hub.start().done(function() { 
      //alert("connection started") 
      getDetails(@Model.Customer.SONumber.ToString()); 
     }).fail(function (e) { 
      alert(e); 
     }); 
    }); 

    function getDetails(sonumber) { 
     if(sonumber = (@Model.Customer.SONumber.ToString())){ 
      var tbl = $('#systemDetails'); 
      $.ajax({ 
       url: '/Monitoring/GetDetails/@Model.Customer.SONumber.ToString()', 
       contentType: 'application/html ; charset:utf-8', 
       type: 'GET', 
       dataType: 'html', 
       cache: false 
      }).success(function (result) { 
       tbl.empty().append(result); 
      }).error(function() { 

      }); 
     } 
    } 
</script> 
} 

局部視圖的相關樣本:(如果有更多的代碼,你想看到的,請索取)

@foreach (var category in Model.Devices.Select(d => d.Room).Distinct()) 
{ 
    <table class="table-borderless"> 
     <tr> 
      <td valign="middle"><i class="glyphicon glyphicon-lg glyphicon-plus-sign" id="categoryToggle"></i></td> 
      <td><h2 class="tableheader">@category</h2></td> 

      @if (Model.Devices.Where(d => d.Room == category).Any(d => d.Status == "Offline")) 
      { 
       <td valign="middle"><i class="glyphicon glyphicon-lg glyphicon-warning-sign"></i></td> 
       <td><h2 class="tableheader">@(Model.Devices.Where(d => d.Room == category && d.Status == "Offline").Count())</h2></td> 
      } 
      else 
      { 
       <td valign="middle"><i class="glyphicon glyphicon-lg glyphicon-ok"></i></td> 
      } 
     </tr> 
    </table> 
    <table style="display:none" class="table"> 
    (...) 

回答

0

這裏有兩種可能的設計路徑:

  1. 切換到更新數據只有,而不是HTML。更改您更新頁面的方式,以便只更新頁面中的數據而不是替換HTML。這將需要重新組織如何獲取和應用更新,但會保留頁面中的所有HTML元素,這樣可見性狀態也會保留。要做到這一點,你可能會從你的服務器請求JSON數據,然後你的客戶端代碼將填充到當前的HTML中。這顯然比你現在做的工作要多,但具有保留所有DOM狀態的優點,因爲DOM元素沒有被替換(除了一些文本節點)。

  2. 保存可見性狀態,然後在更新DOM之後恢復該狀態。如果您打算用新的HTML替換DOM對象,那麼您將需要保存來自原始DOM的可見性設置,然後在用DOM的新部分替換之後,必須將這些早期的可見性設置應用於新的DOM元素。這需要能夠將舊的DOM元素映射到相應的新DOM元素。如果您知道表格行結構保持相同,並且您只是顯示/隱藏行,那麼您可以從字面上僅在代碼中創建一個隱藏行號的數組(例如var hiddenRows = [1,5,6,7,10]),然後再替換DOM部分,然後放入新的HTML,然後去隱藏數組中列出的每一行。

相關問題