【问题标题】:MVP presenter subscribed events after postbackMVP 演示者在回发后订阅了事件
【发布时间】:2012-09-13 10:03:31
【问题描述】:

请参阅下面的更新以获得更简短的说明

我在使用基于事件的 MVP 方法时遇到问题。我有以下设置:

public class MeetingPresenter : IMeetingPresenter
{
     IViewMeeting;
     public MeetingPresenter(IViewMeeting view)
    {
        this.View = view;
        PopulateViewData();
        this.View.MeetingSavedClicked += OnMeetingSavedClicked;
    }

    public void PopulateViewData()
    {
         Imeeting meeting = service.GetMeeting();
         view.SetMeetingDate(meeting.date);
     }

    private void OnMeetingSavedClicked() 
    {
         service.SaveMeeting(view.GetMeeting());
     }
}


public interface IViewMeeting
{
     void SetMeetingDate(Datetime date);
     IMeeting GetMeeting();

     event Action MeetingSavedClicked;
}

然后查看:(用vb写的)

Partial Class MeetingPage
Inherits System.Web.UI.Page
Implements IViewMeeting
{

         Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

           If Not IsPostBack Then
               Presenter = New MeetingPresenter(Me)
           Else

          End If
       End Sub

       Private _presenter As IMeetingPresenter
       Public Property Presenter() As IMeetingPresenter
       Get
           Return _presenter
       End Get
       Set(ByVal value As IMeetingPresenter)
           _presenter = value
       End Set
      End Property

       Public Sub SetMeetingDate(ByVal date As Datetime) Implements IMeetingVisits.SetMeetingDate

           lblMeetingDate.Text = date.Date.ToString()
        End Sub
 }

       //Not implementing this fully - should get the idea
       public Function GetMeeting as IMeeting Implements IMeetingVisits.GetMeeting

       end function

       Event MeetingSavedClicked As Action Implements IViewMeeting.MeetingSavedClicked


       Public Sub btnSaveMeeting_Click(ByVal sender As Object, ByVal e As System.EventArgs)

           RaiseEvent MeetingSavedClicked()
        End Sub
  • 在继续之前 - 我意识到我可以在 View 等中取出依赖项,并且任何模型都应该是 View 特定的。 *

我遇到的问题是事件。我在我的演示者中订阅了 View 界面事件。加载时视图正在创建此演示者的具体版本,这会导致演示者填充所有视图字段。到现在为止还挺好。

问题是当通过btnSaveMeeting_Click 引发MeetingSavedClicked 事件时,没有触发presenter 中相应的订阅方法。这大概是因为演示者不再在内存中,因为回发后状态不保持。我不确定 Presenter 事件中的订阅是否会导致它以某种方式留在内存中(我真的不太了解自定义事件),但似乎情况并非如此。

那么,将演示者存储在视图状态或会话中是唯一的选择吗?这是否意味着事件订阅仍将存在并执行?

抱歉,如果这看起来很基本,但我对事件、MVP 等有点新手。

更新 或许我可以说得更清楚一点:

我的网络表单实现了一个具有动作事件的界面。

网络表单创建一个自定义对象,该对象具有订阅此接口事件的方法。

在回发时,会在 webform 上引发点击事件(代码隐藏),进而引发已实现的界面事件。

现在,自定义对象不再位于网络表单的状态内存中,因为我们处于回发状态(并且自定义对象未存储在会话或视图状态中)。

我订阅的处理程序是否应该仍然存在并且能够捕获这个引发的事件?还是在回发时它们已被“处理​​”?

谢谢。

【问题讨论】:

    标签: c# events event-handling webforms mvp


    【解决方案1】:

    回发中使用的页面对象是一个全新的页面对象。它绝不会连接到您的旧页面对象。要解决您的问题,您必须重新创建您的演示者,并且您必须再次连接事件。

    从技术上讲,如果垃圾收集器尚未收集它们,您的旧页面对象和演示者对象以及它们之间的事件处理程序可能仍在内存中。但是没有对这些对象的引用,它们将/可能在下一次 GC 运行中被收集。

    【讨论】:

    • 所以,最初我们有 WebFormA 和 PresenterA。 PresenterA 填充 WebFormA,并订阅 webformA 中的事件。在回发时,创建/连接 WebFormB 和 PresenterB,并处理单击事件。这会引发 WebformB 事件,PresenterB 订阅了该事件,因此 PresenterB 中的处理程序被触发。同时,订阅了 Webform A 事件的 Presenter A 可用于垃圾回收,因为 WebformA 不再存在。这是正确的吗?我需要确定内存/垃圾,因为我们最近一直在经历内存泄漏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 2015-09-25
    相关资源
    最近更新 更多