AsyncPostBackTriggerによるSPREAD処理によってスクリプトエラーが発生する

文書番号 : 39404     文書種別 : 不具合     登録日 : 2016/04/25     最終更新日 : 2016/09/09
文書を印刷する
対象製品
SPREAD for ASP.NET 8.0J
発生環境
Internet Explorer 8/9
状況
修正済み
詳細
IE8、IE9の利用時、AsyncPostBackTriggerによるSPREAD処理によってスクリプトエラーが発生します。

【再現手順】
1.新規WebフォームにSPREADおよびButtonひとつを配置し、下記の再現コードのようにAsyncPostBackTriggerを設定する
2.Webフォームに下記の再現コードを貼り付け、プロジェクトを起動する
3.Buttonを押下し、子階層を展開したSPREADデータ表示させる
4.Buttonを再度押下する
--- スクリプトエラーが発生する
--- IE9時のエラー: プロパティ"removeData"の値を取得できません。オブジェクトはNullまたは未定義です。
--- IE8時のエラー: エラー: '$element' は Null またはオブジェクトではありません。

【再現コード】
------------------------------------
.aspxファイル body部
------------------------------------
<form id="form1" runat="server">
<div>
  <asp:ScriptManager ID="ScriptManager1" runat="server">
  </asp:ScriptManager>
  <asp:Button ID="Button1" runat="server" Text="Button" />
  <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
      <FarPoint:FpSpread ID="FpSpread1" runat="server" BorderColor="#A0A0A0"
        BorderStyle="Solid" BorderWidth="1px" Height="200" Width="400">
        <commandbar backcolor="#F6F6F6" buttonfacecolor="Control"
          buttonhighlightcolor="ControlLightLight" buttonshadowcolor="ControlDark">
        </commandbar>
        <sheets>
          <FarPoint:SheetView SheetName="Sheet1">
          </FarPoint:SheetView>
        </sheets>
      </FarPoint:FpSpread>
    </ContentTemplate>
    <%-- エラー発生の要因 [2/2] ↓ --%>
    <Triggers>
      <asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
    </Triggers>
    <%-- エラー発生の要因 [2/2] ↑ --%>
  </asp:UpdatePanel>
</div>
</form>

------------------------------------
Webフォームクラス
------------------------------------
Public Class WebForm1
  Inherits System.Web.UI.Page

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

  End Sub

  Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ' データの作成
    Dim maxParentRows As Integer = 10 - 1
    Dim maxChildRows As Integer = 5 - 1
    Dim ds As New DataSet()
    Dim Parent As DataTable = ds.Tables.Add("Parent")
    Parent.DefaultView.AllowNew = False
    Parent.Columns.Add("ParentA", GetType(Int32))
    For i As Integer = 0 To maxParentRows
      Parent.Rows.Add(i)
    Next
    Dim child As DataTable = ds.Tables.Add("Child")
    child.DefaultView.AllowNew = False
    child.Columns.Add("ChildA", GetType(Int32))
    child.Columns.Add("ChildB", GetType(String))
    For i As Integer = 0 To maxParentRows
      For j As Integer = 0 To maxChildRows
        child.Rows.Add(i, String.Format("P{0}C{1}", i, j))
      Next
    Next
    ds.Relations.Add("PCRelation", Parent.Columns("ParentA"), child.Columns("ChildA"))

    ' SPREADの設定
    FpSpread1.ActiveSheetView.DataSource = ds
    FpSpread1.ActiveSheetView.PageSize = 10

    ' エラー発生の要因 [1/2]
    For i As Integer = 0 To FpSpread1.ActiveSheetView.RowCount - 1
      FpSpread1.ActiveSheetView.ExpandRow(i, True)
    Next
  End Sub
End Class
回避方法
Service Pack 3(v8.0.4004.2010)で修正済み。
Service Pack 3(v8.0.4004.2010)より前のバージョンでは次の回避方法が有効です。
------------------------------------------

製品のオブジェクト解放処理を適切に行うことで、本現象の回避が可能です。

【回避コード】
------------------------------------
クライアント側スクリプト
------------------------------------
<script>
  window.onload = function () {
    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequestHandler);

    var app = Sys.Application;
    app.add_unload(ApplicationUnload);
  }

  function ApplicationUnload(sender) {

    Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(beginRequestHandler);
  }

  function beginRequestHandler(sender, args) {
    var updatePanels = args.get_updatePanelsToUpdate();
    if (updatePanels == null || updatePanels.length == 0)
      updatePanels = sender._updatePanelClientIDs;
    if (updatePanels) {
      for (var i = 0; i < updatePanels.length; i++) {
        var pnl = document.getElementById(updatePanels[i]);
        if (pnl) {
          wrapDispose(pnl);
        }
      }
    }

  }

  function wrapDispose(container) {
    var divs = container.getElementsByTagName("DIV");
    for (var i = 0; i < divs.length; i++) {
      var spread = divs[i];
      if (spread.getAttribute("FpSpread") == "Spread" && spread.dispose && !spread.__dispose) {
        spread.__dispose = spread.dispose;
        spread.dispose = __safeDispose;
      }
    }
  }

  function __safeDispose(arg) {
    if (this.__dispose) {
      try {
        if (this.Behavior == null) {
          this.__dispose = null;
          return;
        }
        this.__dispose(arg);
      } catch (e) {
        console.log(e.message);
      }
    }
  }
</script>