WebControl의 ScriptManager.registerStartUpscript를 얻을 수 없습니다.
-
03-07-2019 - |
문제
나는 내가 믿는 것이 상당히 단순한 문제가되어야한다고 믿고 있지만, 내 인생에서는 내 문제를 볼 수 없습니다. 문제는 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);
문제는 페이지가 처음 표시되면 스크립트가 올바르게 실행되지만 부분 포스트 백 후에는 다시 실행되지 않는다는 것입니다. 다음을 시도했습니다.
- CreateChildControls에서 RegisterStartUpscript 호출
- Onload / OnPrerender에서 RegisterStartUpscript 호출
- 처음 두 매개 변수에 대해 다른 매개 변수 조합을 사용합니다 (위의 예제에서는 페이지가 페이지이고 유형은 getType ()이지만 컨트롤 자체를 사용하여 시도했습니다).
- 나는 지속성과 새로운 ID를 사용해 보았습니다 (이것이 어느 쪽이든 큰 영향을 미쳐야한다고 생각하지는 않습니다).
- 몇 가지 중단 점을 사용했으며 레지스터 라인이 올바르게 호출되고 있는지 확인했습니다.
내가 시도하지 않은 유일한 것은 컨트롤이 업데이트 패널을 인식해야한다고 생각하지 않기 때문에 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**);