带有ListView和Repeater的ASP.NET中的Model-View-Presenter

时间:2009-11-07 04:43:52

标签: c# asp.net mvp

我一直在使用ASP.NET探索MVP模式,但是在页面上使用数据绑定控件时,我无法在演示者中保留所有表示逻辑。

以下场景和类仅作为示例,我正在使用的实际案例更复杂。任何想法或方向将不胜感激。

假设我有一个显示客户信息的页面,包括姓名和地址。它还使用Repeater控件呈现订单列表。

public class CustomerDto {
    public string Name { get; set; }
    public string Address { get; set; }
    public List<OrderDto> OrderList { get; set; }
}

public class OrderDto {
    public int Id { get; set; }
    public decimal Amount { get; set; }
    public bool IsRush { get; set; }
}

首先,我让演示者在视图上设置了Name,Address和OrdrerList。此时,仍然有一些表示逻辑发生在Repeater的ItemDataBound事件中,具体取决于订单上IsRush的值。在我看来,这个逻辑不属于代码隐藏,而是属于可测试的演示者类。

public interface IOrderView {
    void SetName(string name);
    void SetAddress(string address);
    void SetOrderList(List<OrderDto> orderList);
}

public partial class OrderPage : Page, IOrderView
{
    public void SetName(string name) {
        labelName.Text = name;
    }

    public void SetAddress(string address) {
        labelAddress.Text = address;
    }

    public void SetOrderList(List<OrderDto> orderList) {
        repeaterOrders.DataSource = orderList;
        repeaterOrders.DataBind();
    }

    protected void repeaterOrders_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
            OrderDto orderDto = e.Item.DataItem as OrderDto;
            if (orderDto.IsRush) {
                Label labelOrderId = (Label)e.Item.FindControl("labelOrderId");
                labelOrderId.ForeColor = System.Drawing.Color.Red;
            }
        }
    }
}

看起来转发器中的每个项目都需要自己的Presenter和View,但我没有在任何地方找到任何类似的例子。我想出了几种方法来保持演示者的所有演示逻辑,但他们都觉得自己像是一个黑客,我想知道人们通常会处理这种情况。

谢谢!

2 个答案:

答案 0 :(得分:4)

答案绝对是模糊的边界。为紧急订单更改标签的颜色绝对是视图的范围,但确定紧急订单与正常订单的逻辑不是IMO。

在你的情况下,我想象的是像访客一样。转发器中的Foreach顺序,您将该顺序传递给演示者或控制器,并根据视图不需要的领域知识在视图中调用适当的方法。

OrderDto orderDto = e.Item.DataItem as OrderDto;
controller.Visit(this, orderDto);

//控制器/演示者中的某个地方

void Visit(ISomeView view, OrderDto dto) {
   if (dto.IsRush) {
        view.RenderRushOrder(dto);
   } else {
        view.RenderNornamlOrder(dto);
   }
}

然后视图可以呈现,因为您已经详细说明了。 IMO它很好地分离了责任和我在非MVC ASP.Net中经常使用的东西

希望这有帮助。

答案 1 :(得分:1)

决定是否应用ForeColor是逻辑,必须在演示者中进行测试。

您只需将CssClass或ForeColor属性添加到对象DTO即可。您肯定希望能够根据OnItemDataBound中当前的逻辑来测试属性是否已设置。