JS函数 vs C#

huangapple go评论62阅读模式
英文:

JS function vs C#

问题

Here is the translated content from your provided text:

我对JS和制作Web应用程序相当陌生,我面临的问题是:
我有JS代码,它创建了6个仪表,并且有一个用于更新仪表1值的函数:

<!-- 包括Gauge.js库 -->
<!-- 必须在justgage之前包括Raphael -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.4/raphael-min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.9/justgage.min.js"></script>
<!-- 在页面加载时初始化仪表 -->
<script>
    var gauge1;
    var gauge2;
    var gauge3;
    var gauge4;
    var gauge5;
    var gauge6;

    function updateGaugeValue(newValue, event) {
        event.preventDefault();
        gauge1.refresh(newValue);
    }

    window.onload = function () {

        gauge1 = new JustGage({
            id: "gauge1",
            value: 0,
            min: 0,
            max: 10,
            title: "My Gauge",
            label: "Value"
        });

        gauge2 = new JustGage({
            id: "gauge2",
            value: 0,
            min: 0,
            max: 10,
            title: "My Gauge",
            label: "Value"
        });

        gauge3 = new JustGage({
            id: "gauge3",
            value: 0,
            min: 0,
            max: 10,
            title: "My Gauge",
            label: "Value"
        });

        gauge4 = new JustGage({
            id: "gauge4",
            value: 0,
            min: 0,
            max: 10,
            title: "My Gauge",
            label: "Value"
        });

        gauge5 = new JustGage({
            id: "gauge5",
            value: 0,
            min: 0,
            max: 10,
            title: "My Gauge",
            label: "Value"
        });

        gauge6 = new JustGage({
            id: "gauge6",
            value: 0,
            min: 0,
            max: 10,
            title: "My Gauge",
            label: "Value"
        });

    };

</script>

当我像这样从按钮中调用更新时:

<button onclick="updateGaugeValue(5, event)">点击我</button>

函数通常可以工作并将仪表1的值更改为5。
但是,当我尝试从C#(使用ASP.NET)通过ClientScript这样调用此函数时:

Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "updateGaugeValue(5, event)", true);

什么都不会发生。但是,如果我尝试测试它并像这样弹出"Hello World":

Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "alert('Hello World')", true);

它通常可以正常工作并弹出警报。是否有任何建议?我期望能够从C#代码中调用这个JS函数。

英文:

I am quite new to JS and doing web apps and I am facing this problem:
I have JS code which creates me 6 gauges and function which updates gauge 1 value:

&lt;!-- Include the Gauge.js library --&gt;
&lt;!-- Raphael must be included before justgage --&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.4/raphael-min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.9/justgage.min.js&quot;&gt;&lt;/script&gt;
&lt;!-- Initialize the gauge on page load --&gt;
&lt;script&gt;
var gauge1;
var gauge2;
var gauge3;
var gauge4;
var gauge5;
var gauge6;
function updateGaugeValue(newValue, event) {
event.preventDefault();
gauge1.refresh(newValue);
}
window.onload = function () {
gauge1 = new JustGage({
id: &quot;gauge1&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;My Gauge&quot;,
label: &quot;Value&quot;
});
gauge2 = new JustGage({
id: &quot;gauge2&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;My Gauge&quot;,
label: &quot;Value&quot;
});
gauge3 = new JustGage({
id: &quot;gauge3&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;My Gauge&quot;,
label: &quot;Value&quot;
});
gauge4 = new JustGage({
id: &quot;gauge4&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;My Gauge&quot;,
label: &quot;Value&quot;
});
gauge5 = new JustGage({
id: &quot;gauge5&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;My Gauge&quot;,
label: &quot;Value&quot;
});
gauge6 = new JustGage({
id: &quot;gauge6&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;My Gauge&quot;,
label: &quot;Value&quot;
});
};
&lt;/script&gt;

When I call update from button like this

&lt;button onclick=&quot;updateGaugeValue(5, event)&quot;&gt;Click me&lt;/button&gt;

function normally works and change value of gauge 1 to 5.
But when I try to call this function from C# (using ASP.NET) via ClientScript like:

Page.ClientScript.RegisterStartupScript(this.GetType(), &quot;CallMyFunction&quot;, &quot;updateGaugeValue(5, event)&quot;, true);

nothing happens. But if I try to test it and alert hello world like

Page.ClientScript.RegisterStartupScript(this.GetType(), &quot;CallMyFunction&quot;, &quot;alert(&#39;Hello World&#39;)&quot;, true);

it normally works and alert. Any suggestions? I expect that I am able to call this JS function from C# code.

答案1

得分: 1

以下是您要翻译的内容:

所以问题在于我们在页面加载/就绪时设置、创建和渲染仪表。

但是,我们想要一个普通的ASP.NET按钮,比如一个文本框,然后一些后台代码来设置值。

问题在于窗口加载。如果我们“注入”对该例程的调用,我们无法(很好地)控制我们的注册表启动脚本何时运行,与现有的设置+创建仪表的代码相对。

所以,我们需要做的是“强制”我们的启动脚本等待。一种很好的方法是使用setTimeout,这将有效地“推送”我们的代码到JavaScript引擎的“执行堆栈”上等待,渲染页面,运行仪表设置代码,然后运行我们需要的代码。

更糟糕的是?对此进行了一些测试,似乎event.prevent似乎会弄乱它。

所以,这是一个可行的概念:

我们将脚本库代码放在顶部,例如:

&lt;title&gt;&lt;/title&gt;
&lt;script src=&quot;../Scripts/jquery-1.12.4.js&quot;&gt;&lt;/script&gt;
&lt;link href=&quot;../Content/bootstrap.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;script src=&quot;../Scripts/bootstrap.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.4/raphael-min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.9/justgage.min.js&quot;&gt;&lt;/script&gt;

但是,对于我们的代码,我们希望将这些内容放在底部-在DOM被创建、设置和渲染之后。

所以,现在这段代码:

    &lt;div style=&quot;padding:35px&quot;&gt;
&lt;div style=&quot;border: solid 1px; float: left; padding: 8px&quot;&gt;
&lt;legend&gt;客户端按钮&lt;/legend&gt;
&lt;button style=&quot;float: left&quot; onclick=&quot;updateGaugeValue(4, event)&quot;&gt;点击我&lt;/button&gt;
&lt;button style=&quot;float: left; margin-left: 25px&quot; onclick=&quot;updateGaugeValue2(6, event)&quot;&gt;点击我&lt;/button&gt;
&lt;/div&gt;
&lt;div style=&quot;float: left; margin-left: 30px; padding: 8px; border: solid 1px&quot;&gt;
&lt;legend&gt;服务器端按钮&lt;/legend&gt;
&lt;div style=&quot;float:left&quot;&gt;
为gauge1输入1-10的值:
&lt;br /&gt;
&lt;asp:TextBox ID=&quot;TextBox1&quot; runat=&quot;server&quot; Width=&quot;50px&quot;&gt;
&lt;/asp:TextBox&gt;
&lt;asp:Button ID=&quot;cmdGauge1&quot; runat=&quot;server&quot;
Text=&quot;设置gauge 1&quot;
CssClass=&quot;btn&quot;
OnClick=&quot;cmdGauge1_Click&quot; /&gt;
&lt;/div&gt;
&lt;div style=&quot;float: left; margin-left: 30px&quot;&gt;
为gauge2输入1-10的值:
&lt;br /&gt;
&lt;asp:TextBox ID=&quot;TextBox2&quot; runat=&quot;server&quot; Width=&quot;50px&quot;&gt;
&lt;/asp:TextBox&gt;
&lt;asp:Button ID=&quot;cmdGauge2&quot; runat=&quot;server&quot;
Text=&quot;设置gauge 2&quot;
CssClass=&quot;btn&quot;
OnClick=&quot;cmdGauge2_Click&quot; /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;clear: both; height: 50px&quot;&gt;
&lt;/div&gt;
&lt;div id=&quot;gauge1&quot; style=&quot;float:left;width:250px;&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;gauge2&quot; style=&quot;width:200px;float:left; margin-left:40px; width: 250px&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
var gauge1;
var gauge2;
window.onload = function () {
gauge1 = new JustGage({
id: &quot;gauge1&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;文件已上传&quot;,
label: &quot;已上传的Zip文件&quot;,
showInnerShadow: true,
shadowOpacity: 2,
shadowSize: 5,
textRenderer: function () {
return &quot;144 / 400&quot;
}
});
gauge2 = new JustGage({
id: &quot;gauge2&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;我的仪表&quot;,
label: &quot;已上传的Pdf文件&quot;,
showInnerShadow: true,
shadowOpacity: 2,
shadowSize: 5,
});
};
function updateGaugeValue(newValue, event) {
// event.preventDefault();
// alert(&#39;开始&#39;)
gauge1.refresh(newValue);
}
function updateGaugeValue2(newValue, event) {
// event.preventDefault();
gauge2.refresh(newValue);
}
&lt;/script&gt;

所以,我们将我们的启动脚本包装在一个timeout函数中。即使延迟为“1”,它也能工作,因为timeout将我们的代码推送到Java引擎程序堆栈上,因此它在页面上的其他所有内容之后运行。

后台代码:

    protected void cmdGauge1_Click(object sender, EventArgs e)
{
string
英文:

So the issue is much that we use a page onload/onready to setup, create and render the gauge.

But, we want a plain asp.net button, say maybe a text box, and then some code behind to set the value.

The issue is the on window load. If we "inject" a call to that routine, we can't (very well) control when our registry start up script runs as opposed to the existing code to setup + create the gauges.

So, what we need to do is "force" our startup script to wait. One great way is to use setTimeout, and that will in effect "push" our code to a routine on the JavaScript engine "execution stack" to wait, render page, run that gauge setup code, AND THEN run our desired code.

Worse yet? Testing this a bit, the event.prevent seems to mess this up.

So, here is a working proof of concept:

We put the script library code at top, for example:

&lt;title&gt;&lt;/title&gt;
&lt;script src=&quot;../Scripts/jquery-1.12.4.js&quot;&gt;&lt;/script&gt;
&lt;link href=&quot;../Content/bootstrap.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;script src=&quot;../Scripts/bootstrap.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.4/raphael-min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.9/justgage.min.js&quot;&gt;&lt;/script&gt;

but, for OUR code, we want that stuff to be placed at bottom - after the DOM been created, setup and rendered.

So, now this code:

    &lt;div style=&quot;padding:35px&quot;&gt;
&lt;div style=&quot;border: solid 1px; float: left; padding: 8px&quot;&gt;
&lt;legend&gt;Client side buttons&lt;/legend&gt;
&lt;button style=&quot;float: left&quot; onclick=&quot;updateGaugeValue(4, event)&quot;&gt;Click me&lt;/button&gt;
&lt;button style=&quot;float: left; margin-left: 25px&quot; onclick=&quot;updateGaugeValue2(6, event)&quot;&gt;Click me&lt;/button&gt;
&lt;/div&gt;
&lt;div style=&quot;float: left; margin-left: 30px; padding: 8px; border: solid 1px&quot;&gt;
&lt;legend&gt;Server side buttons&lt;/legend&gt;
&lt;div style=&quot;float:left&quot;&gt;
Enter value 1-10 for gauage1:
&lt;br /&gt;
&lt;asp:TextBox ID=&quot;TextBox1&quot; runat=&quot;server&quot; Width=&quot;50px&quot;&gt;
&lt;/asp:TextBox&gt;
&lt;asp:Button ID=&quot;cmdGauge1&quot; runat=&quot;server&quot;
Text=&quot;set guage 1&quot;
CssClass=&quot;btn&quot;
OnClick=&quot;cmdGauge1_Click&quot; /&gt;
&lt;/div&gt;
&lt;div style=&quot;float: left; margin-left: 30px&quot;&gt;
Enter value 1-10 for gauage2:
&lt;br /&gt;
&lt;asp:TextBox ID=&quot;TextBox2&quot; runat=&quot;server&quot; Width=&quot;50px&quot;&gt;
&lt;/asp:TextBox&gt;
&lt;asp:Button ID=&quot;cmdGauge2&quot; runat=&quot;server&quot;
Text=&quot;set guage 2&quot;
CssClass=&quot;btn&quot;
OnClick=&quot;cmdGauge2_Click&quot; /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;clear: both; height: 50px&quot;&gt;
&lt;/div&gt;
&lt;div id=&quot;gauge1&quot; style=&quot;float:left;width:250px;&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;gauge2&quot; style=&quot;width:200px;float:left; margin-left:40px; width: 250px&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
var gauge1;
var gauge2;
window.onload = function () {
gauge1 = new JustGage({
id: &quot;gauge1&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;Files Uploaded&quot;,
label: &quot;Zip Files Uploaded&quot;,
showInnerShadow: true,
shadowOpacity: 2,
shadowSize: 5,
textRenderer: function () {
return &quot;144 / 400&quot;
}
});
gauge2 = new JustGage({
id: &quot;gauge2&quot;,
value: 0,
min: 0,
max: 10,
title: &quot;My Gauge&quot;,
label: &quot;Pdf Files uploaded&quot;,
showInnerShadow: true,
shadowOpacity: 2,
shadowSize: 5,
});
};
function updateGaugeValue(newValue, event) {
// event.preventDefault();
// alert(&#39;START&#39;)
gauge1.refresh(newValue);
}
function updateGaugeValue2(newValue, event) {
// event.preventDefault();
gauge2.refresh(newValue);
}
&lt;/script&gt;

So, we wrapped our startup script in a timeout function. Even with a delay of "1", it works, since timeout pushed our code to the Java engine program stack, and thus it runs after everything else on that page.

code behind:

    protected void cmdGauge1_Click(object sender, EventArgs e)
{
string jscode =
$@&quot;updateGaugeValue({TextBox1.Text},event)&quot;;
jscode = &quot;setTimeout(function () {&quot; + jscode + &quot;},1)&quot;; 
ClientScript.RegisterStartupScript(Page.GetType(), &quot;myfunc&quot;, jscode, true);
}
protected void cmdGauge2_Click(object sender, EventArgs e)
{
}

and result:

JS函数 vs C#

However, there really not much need to "call" that existing JS routine you have, since the JS object exists (or we assume it will).

So, then this code :

    protected void cmdGauge1_Click(object sender, EventArgs e)
{
string jscode =
$@&quot;gauge1.refresh({TextBox1.Text})&quot;;
jscode = &quot;setTimeout(function () {&quot; + jscode + &quot;},1)&quot;; 
ClientScript.RegisterStartupScript(Page.GetType(), &quot;myfunc&quot;, jscode, true);
}

So, now we don't even call that JS routine, but use the refresh method of the graph object.

So, now, we can put back (un-comment) out the event.preventDefault(), and thus both client side, and server side buttons in above example will now both work.

I should also point out that I used a delay of 1 (1 millisecond). This delay (amount) is not really required, but the FORCE of the routine to be pushed onto the Java engine execution stack is the important part here.

答案2

得分: 0

Apart from moving your scripts to the HEAD tag instead of having them at the end of BODY, you might want to delay the execution of the code coming from C# after the loading is done.

Something like:

window.onload = () => { const event = new Event("dummy"); setTimeout(() => { updateGaugeValue(5, event) }, 0) };

Put that in the Page.ClientScript.RegisterStartupScript(... call.

What it does:

// appending to the queue of onload functions ensures any other variables and functions, that were declared in the main template's scripts, will be defined already.
window.onload = () => {
  const event = new Event("dummy"); // We want some event so that we can call .preventDefault() upon something.
  // There are better ways around it though.

  setTimeout(() => { 
    updateGaugeValue(5, event) 
  }, 0); // setting the timeout to 0 effectively means, execute immediately after the next round of UI updates
};
英文:

Apart from moving your scripts to the HEAD tag instead of having them at the end of BODY, you might want to delay the execution of the code coming from C# after the loading is done.

Something like:

window.onload = () =&gt; { const event = new Event(&quot;dummy&quot;); setTimeout(() =&gt; { updateGaugeValue(5, event) }, 0) };

Put that in the Page.ClientScript.RegisterStartupScript(... call.

What it does:

// appending to the queue of onload functions ensures any other variables and functions, that were declared in main template&#39;s scripts, will be defined already.
window.onload = () =&gt; {
  const event = new Event(&quot;dummy&quot;); // We want some event so that we can call .preventDefault() upon something.
  // There are better ways around it though.

  setTimeout(() =&gt; { 
    updateGaugeValue(5, event) 
  }, 0); // setting timeout to 0 effectively means, execute immediately after next round of UI updates
};

huangapple
  • 本文由 发表于 2023年3月31日 23:40:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900379.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定