这个问题正在被问到,因为我之前没有代表最佳实践的经验
我在html中有一个无序列表,其中整个网站的结构是相同的,但列表的内容可能不同。
示例:
对象列表A
<ul>
<li>
<ul>
<li>A.someMember1</li>
<li>A.someMember2</li>
<li>A.someMember3</li>
</ul>
</li>
</ul>
对象B列表
<ul>
<li>
<ul>
<li>B.someMember1</li>
<li>B.someMember2</li>
<li>B.someMember3</li>
<li>B.someMember4</li>
</ul>
</li>
</ul>
我创建了两个代表:
protected delegate void RenderHtmlMethod(HtmlTextWriter writer);
protected delegate void RenderHtmlMethodWithObjects(HtmlTextWriter writer, object obj);
以及以下方法
private void RenderList(HtmlTextWriter writer, string title, RenderHtmlMethod headingDelegate,
RenderHtmlMethodWithObjects itemsDelegate, object objToRender)
{
writer.RenderBeginTag(HtmlTextWriterTag.Fieldset);
writer.RenderBeginTag(HtmlTextWriterTag.Legend);
writer.HtmlEncode(title);
writer.RenderEndTag();//end Legend
writer.AddAttribute(HtmlTextWriterAttribute.Class, "resultList");
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
{
headingDelegate(writer);
itemsDelegate(writer, objToRender);
}
writer.RenderEndTag();//ul
writer.RenderEndTag(); //fieldset
}
这样,我可以制作渲染标题的方法(只是另一个带有嵌入式ul的li),然后为每个对象列表渲染必要的列表项。
我无法重新定义我的类来实现任何接口,但是,我可以为类创建一个包装器并在那里实现render方法。你怎么看待这个?
我的结构有意义吗?还是我疯了?
答案 0 :(得分:4)
我认为这不是一个糟糕的决定。但是,我认为最好是创建用于生成列表的特殊接口(或抽象类)。
public abstract class ListRenderer
{
public abstract IEnumerable Items {get;}
public abstract String GenerateHeaderText();
public String GenerateItemText(objectItem);
public abstract void RenderList(TextWriter writer);
}
然后,您只需在具体项目周围创建包装器,并将此对象传递给您的generator方法。如果您的列表以通用方式构建,则可以在ListRenderer中实现所有逻辑,然后仅覆盖GenerateHeaderText和GenerateItemText
答案 1 :(得分:0)
为什么要传递代理来执行渲染?你想让每个列表略有不同吗?如果您正在寻找一致性,我只需传递您想要呈现的对象列表以及一些标题文本,并将其全部呈现在您的方法中。例如,我提出的方法签名可能类似于:
private void RenderList<T>(HtmlTextWriter writer, string title, string headerText, List<T> objectsToRender) where T : IRender
话虽如此,如果每个名单都应该以独特的方式呈现,那么我认为你不会比我头脑中的声音更疯狂。
更新
我想我需要扩展我的代码示例......
private void RenderList<T>(HtmlTextWriter writer, string title, string headerText, List<T> objectsToRender) where T : IRender
{
writer.RenderBeginTag(HtmlTextWriterTag.Fieldset);
writer.RenderBeginTag(HtmlTextWriterTag.Legend);
writer.HtmlEncode(title);
writer.RenderEndTag();//end Legend
writer.AddAttribute(HtmlTextWriterAttribute.Class, "resultList");
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
{
writer.RenderBeginTag(HtmlTextWriterTag.Div); //begin Header
writer.AddAttribute(HtmlTextWriterAttribute.Class, "header");
writer.HtmlEncode(headerText);
writer.RenderEndTag(); //end Header
// render all objects
foreach (T obj in objectsToRender)
{
writer.RenderBeginTag(HtmlTextWriterTag.Li); // begin Custom Object Rendering
obj.CustomRender(writer);
writer.RenderEndTag(); // end Custom Object Rendering
}
}
writer.RenderEndTag();//ul
writer.RenderEndTag(); //fieldset
}
// IRender interface
public interface IRender
{
void CustomRender(HtmlTextWriter writer);
}
答案 2 :(得分:0)
我会选择通用方法Render(HtmlTextWriter)
并将所有其他参数定义为类的属性:
interface IRenderable
{
void Render(HtmlTextWriter writer);
}
class ListComponent : IRenderable
{
public List<IRenderable> Items { get; set; }
public string Title { get; set; }
public void Render(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Fieldset);
writer.RenderBeginTag(HtmlTextWriterTag.Legend);
writer.HtmlEncode(Title);
writer.RenderEndTag();//end Legend
writer.AddAttribute(HtmlTextWriterAttribute.Class, "resultList");
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
foreach (var item in Items)
{
writer.RenderBeginTag(HtmlTextWriterTag.Li);
item.Render(writer);
writer.RenderEndTag();//li
}
writer.RenderEndTag();//ul
writer.RenderEndTag(); //fieldset
}
}