2016-07-06 85 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; 
}