33

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

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

<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 で、Type は GetType() ですが、コントロール自体を使用してみました)。
  4. 永続的な新しい ID を使用してみました (いずれにしても、これが大きな影響を与えるとは思いません)。
  5. いくつかのブレークポイントを使用して、Register 行が正しく呼び出されていることを確認しました。

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

上記で私が間違っている可能性があることを誰かが見ることができますか?

ありがとう :)


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

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

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

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

4

10 に答える 10

34

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

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);
于 2009-11-09T16:27:35.260 に答える
15

実際、RegisterStartupScriptのControlオーバーロードを使用する必要があると思います。

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

[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は更新パネルのプレースホルダーです。プレースホルダーには、ボタンなど、他にもいくつかのコントロールがあります。

これは期待どおりに動作しました。ページをロードするか、更新パネルを更新するたびに、「こんにちは」というアラートが表示されました。

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

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

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

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

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

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

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), script, true);
于 2009-04-29T14:35:57.357 に答える
1

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

これを 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私がしばらく前にここに投稿したもののこの部分。

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

于 2009-04-29T20:42:48.300 に答える
1

キーに 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", "");
 }
于 2011-07-25T05:11:23.690 に答える
0
ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(),script,  true );

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

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

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

于 2012-02-02T15:59:44.467 に答える
0

私は多くのことを試しましたが、最終的に最後のパラメーターが false でなければならず<SCRIPT>、java スクリプトにタグを追加する必要があることがわかりました:

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

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), key, script, **false**);
于 2009-05-27T19:07:54.667 に答える
0

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

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) Guid.NewGuid().ToString(), myScript, true);
于 2009-12-22T11:46:33.090 に答える
0

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

于 2011-01-20T07:45:41.547 に答える