2016-07-06 90 views
0

我有Razor模板,可以在IFrame基於所見即所得(目前SCeditor)客戶端樣式。剃刀模板<table>作爲IFrame基於所見即所得的所見即所得的有效純HTML

原始結構,如<p>@Model.Price</p>@(Model.CashOnDelivery ? "cash on delivery" : "transfer")在WYSIWYG中正常工作,但問題與<table>一起出現。現代瀏覽器喜歡修復DOM,而表格標籤之間的Razor語法並不是真正有效的HTML,所以我擁有的肯定不是我所看到的。

例如

當顯示所見即所得的IFrame DOM
<table border="1"> 
    <tr> 
     <th>Name</th> 
     <th>Amount</th> 
     <th>Price</th> 
     <th>TotalPrice</th> 
    </tr> 
    @foreach (var service in Model.Services) 
    {<tr> 
     <td>@service.Name</td> 
     <td>@service.Amount</td> 
     <td>@service.ItemPrice</td> 
     <td>@service.TotalPrice</td> 
    </tr>} 
</table> 

成爲

@foreach (var service in Model.Services) 
{} 
<table border="1"> 
    <tr> 
     <th>Name</th> 
     <th>Amount</th> 
     <th>Price</th> 
     <th>TotalPrice</th> 
    </tr> 
    <tr> 
     <td>@service.Name</td> 
     <td>@service.Amount</td> 
     <td>@service.ItemPrice</td> 
     <td>@service.TotalPrice</td> 
    </tr> 
</table> 

因此,當用戶點擊保存,所見即所得給我基於固定DOM斷碼。 Chrome,Firefox和IE 10+執行大致相同的更正。

我試圖產生一些黑客,像躲在剃刀假屬性,但

  • 源事業剃刀編譯失衡的html標籤,無法在結束標記
  • 屬性是無效的HTML或者

與JS填充表將無法正常工作,因爲模板通常直接發送到電子郵件。從<table>切換到<div>會從表格中去除WYSIWYG功能,所以它也不是一個好的選擇。我可以在一個函數中隱藏表的生成,但同樣,它會阻止所見即所得的風格...

總結:我需要留在剃刀,<table>和動態生成的行,但仍保持所見即所得的能力。最好不要在過程中爲用戶製作模板。我完全沒有想法。

回答

0

嗯,我設法產生一個解決方法。

我改變模板

<table border="1"> 
    <tr> 
     <th>Name</th> 
     <th>Amount</th> 
     <th>Price</th> 
     <th>TotalPrice</th> 
    </tr> 
    @foreach (var service in Model.Services) 
    {<tr razor-outer="foreach (var service in Model.Services)"> 
     <td>@service.Name</td> 
     <td>@service.Amount</td> 
     <td>@service.ItemPrice</td> 
     <td>@service.TotalPrice</td> 
    </tr>} 
</table> 

,然後在所見即所得顯示前前,後與razor-outer屬性<tr>節點只需刪除文本節點。通過在屬性過程中隱藏代碼是完全可逆的並且所見即所得的友好。

public static string PackRazor(string razor) 
{ 
    if (string.IsNullOrWhiteSpace(razor)) 
    { 
     return razor; 
    } 
    HtmlDocument doc = new HtmlDocument(); 

    doc.LoadHtml(razor); 

    string razorOuterXpath = "//*[@razor-outer]"; 

    var nodes = doc.DocumentNode.SelectNodes(razorOuterXpath); 
    if (nodes != null) 
    { 
     foreach (HtmlNode node in nodes) 
     { 
      HtmlAttribute razorAttr = node.Attributes["razor-outer"]; 
      var prev = node.PreviousSibling; 
      var next = node.NextSibling; 

      if (prev.NodeType == HtmlNodeType.Text && prev.InnerHtml.Contains(razorAttr.Value)) 
      { 
       node.ParentNode.RemoveChild(prev); 
      } 
      if (next.NodeType == HtmlNodeType.Text && next.InnerHtml.Contains("}")) 
      { 
       node.ParentNode.RemoveChild(next); 
      } 
     } 
    } 

    return doc.DocumentNode.OuterHtml; 
} 

和保存模板剃鬚刀之前可從屬性恢復

public static string UnpackRazor(string html) 
{ 
    if (string.IsNullOrWhiteSpace(html)) 
    { 
     return html; 
    } 
    HtmlDocument doc = new HtmlDocument(); 

    doc.LoadHtml(html); 

    string razorOuterXpath = "//*[@razor-outer]"; 

    var nodes = doc.DocumentNode.SelectNodes(razorOuterXpath); 
    if (nodes != null) 
    { 
     foreach (HtmlNode node in nodes) 
     { 
      HtmlAttribute razorAttr = node.Attributes["razor-outer"]; 
      var newNode = HtmlNode.CreateNode(html); 
      node.ParentNode.InsertBefore(HtmlNode.CreateNode("@" + razorAttr.Value + "{"), node); 
      node.ParentNode.InsertAfter(HtmlNode.CreateNode("}"), node); 
      Console.WriteLine(razorAttr.Value); 
     } 
    } 

    return doc.DocumentNode.OuterHtml; 
}