asp.net JS函数vs C#

mrzz3bfm  于 2023-04-08  发布在  .NET
关注(0)|答案(2)|浏览(217)

我对JS和Web应用程序很陌生,我面临着这个问题:我有JS代码,它创建了6个 Jmeter 和更新 Jmeter 1值的函数:

<!-- Include the Gauge.js library -->
<!-- Raphael must be included before justgage -->
<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>
        <!-- Initialize the gauge on page load -->
    <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>

当我像这样从按钮调用update时

<button onclick="updateGaugeValue(5, event)">Click me</button>

函数正常工作并将gauge 1的值更改为5。但是当我尝试通过ClientScript从C#(使用ASP.NET)调用此函数时,如下所示:

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

什么也没发生。但是如果我试着测试它并像这样提醒hello world

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

它通常工作和警报。有什么建议吗?
我希望我能够从C#代码调用这个JS函数。

n6lpvg4x

n6lpvg4x1#

好的,问题是我们使用一个页面onload/onready来设置,创建和渲染 Jmeter 。
但是,我们需要一个plane janeasp.net按钮,比如一个文本框,然后一些普通的jane代码来设置值。
问题是窗口加载。如果我们“注入”一个对该例程的调用,我们就不能(很好地)控制我们的寄存器启动脚本何时运行,而不是现有的代码来设置+创建 Jmeter 。
因此,我们需要做的是“强制”我们的启动脚本等待。一个很好的方法是使用setTimeout,这实际上会将我们的代码“推”到JavaScript引擎“执行堆栈”上的一个例程中等待,渲染页面,运行该 Jmeter 设置代码,然后运行我们想要的代码。
更糟的是?测试一下,event.prevent似乎把这搞砸了。
这里是一个可行的概念证明:
标记:
我们把脚本库代码放在最上面:
例如:

<title></title>
<script src="../Scripts/jquery-1.12.4.js"></script>
<link href="../Content/bootstrap.css" rel="stylesheet" />
<script src="../Scripts/bootstrap.js"></script>
<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>

但是,对于我们的代码,我们希望这些东西放在底部-在创建、设置和呈现dom之后。
所以,现在这段代码:

<div style="padding:35px">

        <div style="border: solid 1px; float: left; padding: 8px">
            <legend>Client side buttons</legend>
            <button style="float: left" onclick="updateGaugeValue(4, event)">Click me</button>
            <button style="float: left; margin-left: 25px" onclick="updateGaugeValue2(6, event)">Click me</button>

        </div>

        <div style="float: left; margin-left: 30px; padding: 8px; border: solid 1px">
                <legend>Server side buttons</legend>

            <div style="float:left">
                Enter value 1-10 for gauage1:
                <br />
                <asp:TextBox ID="TextBox1" runat="server" Width="50px">
                </asp:TextBox>
                <asp:Button ID="cmdGauge1" runat="server"
                    Text="set guage 1"
                    CssClass="btn"
                    OnClick="cmdGauge1_Click" />
            </div>

            <div style="float: left; margin-left: 30px">
                Enter value 1-10 for gauage2:
                <br />
                <asp:TextBox ID="TextBox2" runat="server" Width="50px">
                </asp:TextBox>
                <asp:Button ID="cmdGauge2" runat="server"
                    Text="set guage 2"
                    CssClass="btn"
                    OnClick="cmdGauge2_Click" />
            </div>
        </div>

        <div style="clear: both; height: 50px">
        </div>

        <div id="gauge1" style="float:left;width:250px;"></div>

        <div id="gauge2" style="width:200px;float:left; margin-left:40px; width: 250px"></div>

    </div>

<script>
    var gauge1;
    var gauge2;

    window.onload = function () {

        gauge1 = new JustGage({
            id: "gauge1",
            value: 0,
            min: 0,
            max: 10,
            title: "Files Uploaded",
            label: "Zip Files Uploaded",
            showInnerShadow: true,
            shadowOpacity: 2,
            shadowSize: 5,
            textRenderer: function () {
                return "144 / 400"
            }
        });

        gauge2 = new JustGage({
            id: "gauge2",
            value: 0,
            min: 0,
            max: 10,
            title: "My Gauge",
            label: "Pdf Files uploaded",
            showInnerShadow: true,
            shadowOpacity: 2,
            shadowSize: 5,

        });
    };

    function updateGaugeValue(newValue, event) {
        // event.preventDefault();
        // alert('START')
        gauge1.refresh(newValue);
    }
    function updateGaugeValue2(newValue, event) {
        // event.preventDefault();
        gauge2.refresh(newValue);
    }

</script>

因此,我们将启动脚本 Package 在一个timeout函数中。即使使用“1”,它也能工作,因为timeout将我们的代码推到javaengine程序堆栈中,因此它在页面上的其他内容之后运行。
后面的代码:

protected void cmdGauge1_Click(object sender, EventArgs e)
    {
        string jscode =
            $@"updateGaugeValue({TextBox1.Text},event)";

        jscode = "setTimeout(function () {" + jscode + "},1)"; 
        ClientScript.RegisterStartupScript(Page.GetType(), "myfunc", jscode, true);
    }

    protected void cmdGauge2_Click(object sender, EventArgs e)
    {

    }

结果:

然而,真的不需要“调用”现有的js例程,因为js对象已经存在(或者我们假设它会存在)。
那么,这段代码:

protected void cmdGauge1_Click(object sender, EventArgs e)
    {
        string jscode =
            $@"gauge1.refresh({TextBox1.Text})";

        jscode = "setTimeout(function () {" + jscode + "},1)"; 
        ClientScript.RegisterStartupScript(Page.GetType(), "myfunc", jscode, true);
    }

所以,现在我们甚至不调用那个js例程,而是使用graph对象的refresh方法。
所以,现在,我们可以把back(un-comment)out事件.preventDefault();因此,上述示例中的客户端和服务器端按钮现在都将“都”工作。
我还应该指出,我使用了1(1毫秒)的延迟。这个延迟(量)并不是真正需要的,但是要推送到Java引擎执行堆栈上的例程的FORCE是这里重要的部分。

uajslkp6

uajslkp62#

除了将脚本移到HEAD标记而不是BODY的末尾之外,您可能希望在加载完成后延迟执行来自C#的代码。
类似于:

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

把它放在Page.ClientScript.RegisterStartupScript(...调用中。
它的作用:

// appending to the queue of onload functions ensures any other variables and functions, that were declared in 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 timeout to 0 effectively means, execute immediately after next round of UI updates
};

相关问题