문제

나는 내가 믿는 것이 상당히 단순한 문제가되어야한다고 믿고 있지만, 내 인생에서는 내 문제를 볼 수 없습니다. 문제는 ScriptManager.registerStartUpscript와 관련이 있습니다.

내가 가진 시나리오는 페이지에 삽입 된 사용자 정의 웹 컨트롤이 있다는 것입니다. 컨트롤 (및 한두 가지)은 업데이트 패널 내부에 중첩됩니다. 그들은 페이지에 자리 표시 자에 삽입됩니다.

<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. 처음 두 매개 변수에 대해 다른 매개 변수 조합을 사용합니다 (위의 예제에서는 페이지가 페이지이고 유형은 getType ()이지만 컨트롤 자체를 사용하여 시도했습니다).
  4. 나는 지속성과 새로운 ID를 사용해 보았습니다 (이것이 어느 쪽이든 큰 영향을 미쳐야한다고 생각하지는 않습니다).
  5. 몇 가지 중단 점을 사용했으며 레지스터 라인이 올바르게 호출되고 있는지 확인했습니다.

내가 시도하지 않은 유일한 것은 컨트롤이 업데이트 패널을 인식해야한다고 생각하지 않기 때문에 updatepanel 자체를 컨트롤 및 유형으로 사용하는 것입니다. 패널?).

위에서 내가 잘못하고있는 일을 볼 수 있습니까?

감사 :)


글쎄, 위의 쿼리에 답하기 위해 - 자리 표시자가 어떻게 든 scriptmanager.registerstartupscript를 엉망으로 만드는 것처럼 보입니다.

자리 표시 자에서 컨트롤을 꺼내고 페이지에 직접 코딩하면 레지스터 스크립트가 올바르게 작동합니다 (또한 컨트롤 자체를 매개 변수로 사용하고 있습니다).

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

자리 표시 자에게 주입 된 제어가 왜 스크립트 관리자가 스크립트를 올바르게 등록하지 못하게하는지에 대해 조명 할 수 있습니까? 나는 이것이 동적 컨트롤의 수명주기와 관련이 있을지 모르지만, 위의 올바른 과정이 있다면 내 자신의 지식을 위해 감사 할 것입니다.

도움이 되었습니까?

해결책

나는 당신이 실제로 사용해야한다고 생각합니다 제어 과부하 registerStartUpscript의

서버 컨트롤에서 다음 코드를 시도했습니다.

[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());
}

여기서 자리 표시기 1은 업데이트 패널의 자리 표시 자입니다. 자리 표시자는 버튼을 포함하여 몇 가지 다른 컨트롤이 있습니다.

이것은 당신이 예상 한대로 정확하게 행동했습니다. 페이지를로드하거나 업데이트 패널이 업데이트 될 때마다 "Hello"라는 경고를 받았습니다.

당신이 볼 수있는 또 다른 것은 업데이트 패널 요청 중에 해고 된 일부 페이지 라이프 사이클 이벤트에 연결하는 것입니다.

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

그만큼 PageRequestManager endRequestHandler 업데이트 패널이 업데이트를 완료 할 때마다 이벤트가 발생합니다.이를 통해 컨트롤을 설정하는 메소드를 호출 할 수 있습니다.

나의 유일한 다른 질문은 다음과 같습니다.

  • 스크립트는 실제로 무엇을하고 있습니까?
  • 아마도 페이지 하단의 HTML에서 스크립트를 볼 수 있습니다 (폐쇄 직전u003C/form> 꼬리표)?
  • 몇 가지 "Alert ("Here ");" 스타트 업 스크립트에서 호출하여 올바르게 호출되는지 확인하십시오.
  • Firefox를 사용해 보셨습니까? 개똥 벌레 - 스크립트 오류를보고합니까?

다른 팁

사용자 컨트롤에서 이것을 사용하는 문제가있었습니다 (페이지에서는 잘 작동했습니다). 버튼 1은 안에 있습니다 updatepanel, 그리고 scriptmanager 에 있습니다 usercontrol.

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

이제 처음 두 가지 인수에주의 해야하는 것 같습니다. 통제가 아닌 귀하의 페이지를 참조해야합니다.

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

scriptManager.registerStartUpscript를 호출 할 때 "Control"매개 변수는 업데이트 될 UpdatePanel 내에있는 컨트롤이어야합니다. 다음으로 변경해야합니다.

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

솔루션은 스크립트를 외부 JS 파일 ( 'yourdynamic.js'라고 부르면)에 스크립트를 넣고 updatepanel을 새로 고칠 때마다 파일을 다시 등록하는 것입니다.

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;
                }
            }
        }
    }
}

꽤 멋지다, 아 ... 제이 제이 내가 얼마 전에 게시 한 내용 의이 부분 여기.

이 도움을 바랍니다 ... :)

Page.clientscript.registerStartUpscript에 문제가있었습니다. 업데이트 패널을 사용하지 않았지만 컨트롤이 캐시되었습니다. 이것은 캐시에서 렌더링 할 때 스크립트를 리터럴에 (또는 자리 표시자를 사용할 수 있음) 스크립트에 삽입해야한다는 것을 의미했습니다.

비슷한 솔루션이 효과가있을 수 있습니다.

키를 위해 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", "");
 }

나에게 효과가있는 것은 페이지에 등록하는 동시에 UpdatePanel의 유형을 지정하는 것입니다.

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

스크립트에 구문 오류가있을 때 발생하지 않아도 스크립트와 JavaScript 구문이 올바른지 확인하십시오.

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

ScriptManager.registerStartUpscript의 끝에있는 "true"param 값은 페이지 내에 JavaScript 태그를 추가합니다.

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

값이 "false"인 경우-스크립트-태그가있는 스크립트 만 주입합니다.

나는 많은 것을 시도하고 마지막으로 마지막 매개 변수가 거짓이어야한다는 것을 알았으며 당신은 추가해야합니다. <SCRIPT> Java 스크립트에 태그 :

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

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), key, script, **false**);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top