JS-функция против C#

Я новичок в JS и делаю веб-приложения, и я столкнулся с этой проблемой: У меня есть код JS, который создает мне 6 датчиков и функцию, которая обновляет значение датчика 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>

Когда я вызываю обновление с такой кнопки

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

функция нормально работает и измените значение датчика 1 на 5. Но когда я пытаюсь вызвать эту функцию из С# (используя ASP.NET) через ClientScript, например:

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

Ничего не произошло. Но если я попытаюсь проверить это и предупредить привет, мир, как

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

он нормально работает и предупреждает. Какие-либо предложения?

Я ожидаю, что смогу вызвать эту функцию JS из кода C#.

Нет event, когда вы вызываете "updateGaugeValue(5, event)", регистрируя его как сценарий запуска.

VLAZ 31.03.2023 17:42

Просто проверьте, существует ли event перед вызовом preventDefault() (т. е. if (event) { event.preventDefault(); }). Затем в вашем вызове RegisterStartupScript просто вызовите функцию без event (т. е. "updateGaugeValue(5)").

Heretic Monkey 31.03.2023 17:46

Пробовал, с кнопки работает нормально, а с c# опять нет

MART 31.03.2023 17:49

Что говорит консоль? В инструментах разработчика браузера. Нажатие F12 в вашем браузере обычно открывает инструменты разработчика.

Klímačka 31.03.2023 17:51

Homepage.aspx:96 Uncaught ReferenceError: updateGaugeValue не определено на Homepage.aspx:96:1

MART 31.03.2023 17:53

Затем переместите свои сценарии в тег HEAD. Я думаю, они у вас в конце BODY, верно?

Klímačka 31.03.2023 17:54

Да, ты прав. Все еще не работает, но я получаю другую ошибку: Uncaught TypeError: Не удается прочитать свойства неопределенного (чтение «обновить») в updateGaugeValue (Homepage.aspx:25:20) в Homepage.aspx:176:1

MART 31.03.2023 17:56

Подождите, я напишу правильный ответ...

Klímačka 31.03.2023 17:57

Причина, по которой вы получали Cannot read properties of undefined (reading 'refresh'), заключается в том, что у вас есть неопределенная переменная только во время выполнения JS, пришедшего из C#. Переменная window.gauge1 определяется в событии «загрузка» (поскольку вы определяете обратный вызов onload, назначая window.onload = ...

Klímačka 31.03.2023 18:11
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
9
91
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Помимо перемещения ваших сценариев в тег 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
};

Я немного смущен сейчас. Весь этот блок кода я должен поместить в функцию RegisterStartupScript в качестве параметра скрипта?

MART 31.03.2023 18:15

Да. Метод RegisterStartupScript создает тег SCRIPT и вставляет содержимое в параметр внутри. Так что в нем можно писать довольно длинные скрипты.

Klímačka 31.03.2023 18:20

Итак, если я назову это: Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "window.onload = () => { const event = new Event(\"dummy\"); setTimeout(() => { updateGaugeValue(5, event) }, 0) };", true); есть 2 возможности: 1. иметь код JS внизу - нет никакой ошибки, но ничего не меняется 2. поместить код JS в тег заголовка - когда эта функция вызывается, я получаю снова ошибка не может прочитать свойства, и все мои датчики исчезают с моей веб-страницы

MART 31.03.2023 18:24

И функция по-прежнему выглядит так: function updateGaugeValue(newValue, event) { event.preventDefault(); gauge1.refresh(newValue); }

MART 31.03.2023 18:26

Удалите загрузку и просто вызовите ее снизу тела

Klímačka 31.03.2023 19:04
Ответ принят как подходящий

Таким образом, проблема заключается в том, что мы используем страницу onload/onready для настройки, создания и отображения датчика.

Но нам нужна простая кнопка asp.net, скажем, текстовое поле, а затем некоторый код для установки значения.

Проблема в загрузке окна. Если мы «внедряем» вызов этой процедуры, мы не можем (очень хорошо) контролировать, когда запускается сценарий запуска нашего реестра, в отличие от существующего кода для настройки + создания датчиков.

Итак, что нам нужно сделать, так это «заставить» наш сценарий запуска ждать. Одним из отличных способов является использование setTimeout, и это фактически «подтолкнет» наш код к подпрограмме в «стеке выполнения» движка JavaScript, чтобы дождаться, отобразить страницу, запустить этот код настройки датчика, а ЗАТЕМ запустить желаемый код.

Еще хуже? Немного протестировав это, 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>

Итак, мы завернули наш скрипт запуска в функцию тайм-аута. Даже с задержкой «1» это работает, поскольку тайм-аут поместил наш код в программный стек движка Java, и, таким образом, он запускается после всего остального на этой странице.

код позади:

    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-процедуру, а используем метод обновления графического объекта.

Итак, теперь мы можем вернуть (раскомментировать) event.preventDefault(), и, таким образом, обе кнопки на стороне клиента и на стороне сервера в приведенном выше примере теперь будут работать.

Я также должен указать, что я использовал задержку 1 (1 миллисекунда). Эта задержка (количество) на самом деле не требуется, но СИЛА подпрограммы, которая должна быть помещена в стек выполнения механизма Java, является важной частью здесь.

У меня есть еще один вопрос, связанный с проблемой ... когда я вызываю ClientScript из функции, которая занимает 6 секунд, значение датчика изменяется на моей веб-странице после того, как вся функция выполнена, вместо этого я вызываю его при запуске своей функции, есть предложения?

MART 01.04.2023 00:59

Порядок кода позади, как правило, не имеет значения. При обратной передаче ВСЯ веб-страница находится на сервере. Вы можете в коде изменить элементы управления или что-то еще, но пока ПОЛНАЯ обратная передача не будет завершена на 100%, веб-страница не вернется на сторону клиента. Итак, если что-то занимает 6 секунд, то вся страница все еще находится на сервере. Код позади, чтобы изменить элемент управления, зарегистрировать скрипт или что-то еще? Вы не увидите ни одного из этих кумулятивных изменений до тех пор, пока обратная передача не будет завершена на 100%, поскольку веб-страница находится на сервере, измененном кодом позади - только после того, как все изменения передаются клиенту.

Albert D. Kallal 01.04.2023 04:11

Неясно, можно ли разбить части этого кода, но если этот код занимает 6 секунд, тогда вы будете ждать 6 секунд, верно? Не совсем уверен на 100%, что вы спрашиваете здесь? Возможно, вы могли бы отобразить страницу и «затем» вызвать код для установки/загрузки значения датчика. В этом случае, вероятно, можно было бы рассмотреть ajax-вызов веб-метода.

Albert D. Kallal 01.04.2023 04:11

Я делаю веб-страницы, которые проверяют скорость запросов к базам данных... Поэтому, когда я нажимаю кнопку и запускаю функцию, появляется цикл for, который выполняет некоторое количество запросов, эта функция включает таймер, и я хочу обновить значение датчика после каждый запрос выполняется, это как-то возможно?

MART 01.04.2023 10:27

Конечно, вы можете, но для этого потребуется некоторый тип таймера на стороне клиента и подход к обновлению. У вас не может быть «временной задержки» на стороне сервера для таких обновлений, поскольку, как уже отмечалось, вы ДОЛЖНЫ понять концепцию кругового пути. Таким образом, это можно сделать либо с помощью элемента управления таймером, либо даже с помощью кода JavaScript на стороне клиента + вызовов веб-методов. Чтобы понять, «почему» вы не можете использовать задержку на стороне сервера, прочитайте мой недавний ответ: stackoverflow.com/questions/75878021/…

Albert D. Kallal 01.04.2023 16:17

Этот ответ содержит ссылки на «движок Java», но мне интересно, имелся ли в виду «движок JavaScript» (то есть интерпретатор JS в браузере).

halfer 28.05.2023 11:55

Другие вопросы по теме