web-dev-qa-db-ja.com

UpdatePanelにネストされたWebControlのScriptManager.RegisterStartupScriptが機能しない

私はかなり単純な問題であると信じているものを抱えていますが、私の人生では問題を見ることができません。この問題は、ScriptManager.RegisterStartupScriptに関連しています。これは、以前に何度も使用したことのあるものです。

私が持っているシナリオは、ページに挿入されたカスタムWebコントロールがあるということです。コントロール(および他の1つまたは2つ)は、UpdatePanel内にネストされます。それらは、ページのPlaceHolderに挿入されます。

<asp:UpdatePanel ID="pnlAjax" runat="server">
  <ContentTemplate>
    <asp:PlaceHolder ID="placeholder" runat="server">
    </asp:PlaceHolder>
    ...

protected override void OnInit(EventArgs e){
  placeholder.Controls.Add(Factory.CreateControl());
  base.OnInit(e);
}

これはページ上の唯一の更新パネルです。

コントロールを正常に動作させるには、いくつかの初期javascriptを実行する必要があります。コントロールは以下を呼び出します:

ScriptManager.RegisterStartupScript(this, GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

私も試しました:

ScriptManager.RegisterStartupScript(Page, Page.GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

問題は、ページが最初に表示されたときにスクリプトが正しく実行されますが、部分的なポストバック後に再実行されないことです。私は次を試しました:

  1. CreateChildControlsからRegisterStartupScriptを呼び出す
  2. OnLoad/OnPreRenderからRegisterStartupScriptを呼び出す
  3. 最初の2つのパラメーターにパラメーターの異なる組み合わせを使用します(上記の例では、コントロールはPageであり、タイプはGetType()ですが、コントロール自体を使用するなど)。
  4. 永続的な新しいIDを使用してみました(これがいずれにせよ大きな影響を与えると信じているわけではありません)。
  5. いくつかのブレークポイントを使用して、Register行が正しく呼び出されることを確認しました。

私が試したことのない唯一のことは、コントロールが更新パネルを認識する必要があるとは思わないので、UpdatePanel自体をコントロールとタイプとして使用することです(いずれにしても、更新を取得する良い方法はないようですパネル?)。

上記で私が間違っているかもしれないことを誰でも見ることができますか?

ありがとう:)


さて、上記のクエリに答えるには、プレースホルダがScriptManager.RegisterStartupScriptを何らかの方法で台無しにしているかのように見えます。

コントロールをプレースホルダーから引き出してページに直接コーディングすると、Registerスクリプトが正しく機能します(コントロール自体もパラメーターとして使用しています)。

 
 ScriptManager.RegisterStartupScript(this、GetType()、Guid.NewGuid()。ToString()、script、true); 
 

PlaceHolderにコントロールを挿入すると、ScriptManagerがスクリプトを正しく登録できなくなる理由について、誰もが明かりを灯すことができますか?これは動的コントロールのライフサイクルに関係しているのではないかと推測していますが、上記の正しいプロセスがあれば感謝します(私の知る限り)。

33
Chris

RegisterStartupScriptの Control overload を実際に使用する必要があると思います。

サーバーコントロールで次のコードを試しました。

[ToolboxData("<{0}:AlertControl runat=server></{0}:AlertControl>")]
public class AlertControl : Control{
    protected override void OnInit(EventArgs e){
        base.OnInit(e);
        string script = "alert(\"Hello!\");";
        ScriptManager.RegisterStartupScript(this, GetType(), 
                      "ServerControlScript", script, true);
    }
}

それから私のページで私は持っています:

protected override void OnInit(EventArgs e){
    base.OnInit(e);
    Placeholder1.Controls.Add(new AlertControl());
}

Placeholder1は、更新パネルのプレースホルダーです。プレースホルダーには、ボタンなどの他のコントロールがいくつかあります。

これは期待どおりに動作し、ページをロードするたびに、または更新パネルを更新するたびに「Hello」というアラートを受け取りました。

あなたが見ることができる他のことは、更新パネルのリクエスト中に発生するページのライフサイクルイベントのいくつかにフックすることです:

Sys.WebForms.PageRequestManager.getInstance()
   .add_endRequest(EndRequestHandler);

PageRequestManager endRequestHandler イベントは、更新パネルが更新を完了するたびに発生します。これにより、コントロールをセットアップするメソッドを呼び出すことができます。

私の他の質問は次のとおりです。

  • あなたのスクリプトは実際に何をしていますか?
  • おそらく、ページの下部(終了</ form>タグの直前)のHTMLでスクリプトを見ることができますか?
  • いくつかの「alert( "Here");」を入れてみましたか?起動スクリプトを呼び出して、正しく呼び出されているかどうかを確認しますか?
  • Firefoxを試してみました Firebug -スクリプトエラーを報告していますか?
15

ユーザーコントロールでこれを使用する際に問題が発生しました(ページ内で正常に機能しました)。 Button1はupdatepanel内にあり、scriptmanagerusercontrol上にあります。

protected void Button1_Click(object sender, EventArgs e)  
{  
    string scriptstring = "alert('Welcome');";  
    ScriptManager.RegisterStartupScript(this, this.GetType(), "alertscript", scriptstring, true);  
}

今、あなたは最初の2つの引数に注意する必要があるようです、彼らはあなたのコントロールではなくあなたのページを参照する必要があります

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alertscript", scriptstring, true);
34
dc2009

ScriptManager.RegisterStartupScriptを呼び出す場合、「Control」パラメーターは、更新されるUpdatePanel内にあるコントロールでなければなりません。次のように変更する必要があります。

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), script, true);
10
Keltex

解決策は、スクリプトを外部のjsファイル(「yourDynamic.js」と呼ばれる)に配置し、updatepanelを更新するたびにdeファイルを再登録することです。

Updatepanel_prerenderイベントでこれを使用します。

ScriptManager.RegisterClientScriptBlock(UpdatePanel1, UpdatePanel1.GetType(), "UpdatePanel1_PreRender", _
                   "<script type='text/javascript' id='UpdatePanel1_PreRender'>" & _
                   "include('yourDynamic.js');" & _
                   "removeDuplicatedScript('UpdatePanel1_PreRender');</script>" _
                   , False)

ページまたはその他のインクルードには、次のjavascriptが必要です。

// Include a javascript file inside another one.
function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].getAttribute('src'))
        {
            if(scripts[x].getAttribute('src').indexOf(filename) != -1)
            {
                head.removeChild(scripts[x]);
                break;
            }
        }
    }

    script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';
    head.appendChild(script)
}

// Removes duplicated scripts.
function removeDuplicatedScript(id)
{
    var count = 0;
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    var firstScript;
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].getAttribute('id'))
        {
            if(scripts[x].getAttribute('id').indexOf(id) != -1)
            {
                if (count == 0)
                {
                    firstScript = scripts[x];
                    count++;
                }
                else
                {
                    head.removeChild(firstScript);
                    firstScript = scripts[x];
                    count = 1;
                }
            }
        }
    }
    clearAjaxNetJunk();
}
// Evoids the update panel auto generated scripts to grow to inifity. X-(
function clearAjaxNetJunk()
{
    var knowJunk = 'Sys.Application.add_init(function() {';
    var count = 0;
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    var firstScript;
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].textContent)
        {
            if(scripts[x].textContent.indexOf(knowJunk) != -1)
            {
                if (count == 0)
                {
                    firstScript = scripts[x];
                    count++;
                }
                else
                {
                    head.removeChild(firstScript);
                    firstScript = scripts[x];
                    count = 1;
                }
            }
        }
    }
}

かなりクール、ああ... jejeje少し前に投稿したもののこの部分 here

この助けを願っています... :)

1
Lucas

GUIDキーには使用しないでください

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) 
       Guid.NewGuid().ToString(), myScript, true);

そして、あなたがそれをしたい場合は、この関数のような何かを呼び出します

 public static string GetGuidClear(string x)
 {
      return x.Replace("-", "").Replace("0", "").Replace("1", "")
              .Replace("2",  "").Replace("3", "").Replace("4", "")
              .Replace("5", "").Replace("6", "").Replace("7", "")
              .Replace("8", "").Replace("9", "");
 }
1
ahmad sarkar

Page.ClientScript.RegisterStartUpScriptで問題が発生しました-更新パネルを使用していませんでしたが、コントロールはキャッシュされていました。つまり、スクリプトをLiteralに挿入する必要があった(またはPlaceHolderを使用できた)ため、キャッシュからレンダリングするときにスクリプトが含まれます。

同様の解決策が役に立つかもしれません。

1
s_hewitt

私のために働いたのは、次のようにタイプをUpdatePanelのタイプとして指定しながらページに登録することです:

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) Guid.NewGuid().ToString(), myScript, true);
0
Alex
ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(),script,  true );

ScriptManager.RegisterStartupScriptの最後にある「true」パラメータ値は、ページ内にJavaScriptタグを追加します。

<script language='javascript' defer='defer'>your script</script >

値が「false」の場合、-script--タグなしでスクリプトのみが挿入されます。

0
ZoharAdar

スクリプトに構文エラーがある場合は起動しないことがあります。スクリプトとjavascriptの構文が正しいことを確認してください。

0
Prema Tiwari

私は多くのことを試してみましたが、最後のパラメーターはfalseでなければならず、<SCRIPT>タグJavaスクリプト:

string script = "< SCRIPT >alert('hello!');< /SCRIPT>";

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), key, script, **false**);
0
Steve