[BugFixed]
Проверка наличия ссылки на объект (не NULL)
Автор |
Сообщение |
Сообщение создано: 17. 11. 2018 [23:28]
|
kantv
Антон Калюк
Создатель темы
Зарегистрирован(а) с: 29.11.2016
Сообщения: 17
|
Доброго времени суток.
Подскажите, что вернет метод виджета this.wdgAt(<путь>, true), если по указанному пути ничего нет, или другими словами по указанному пути нет объектов?
Я хотел бы после получения результата как то проверить его на валидность, то есть проверить, что в результате был получен какой-то объект. В других языках, например в C# для пустых ссылок на объект есть встроенное значение NULL, сравнивая с которым можно произвести проверку на наличие объекта перед тем как пытаться вызывать его методы. Есть ли какой-то аналог NULL в JavaLikeCalk у OpenSCADA?
То есть как можно реализовать примерно такую конструкцию?
obj = this.wdgAt(<путь>, true);
if (obj != null) {
//объект найден и можно над ним выполнять какие-то операции
} else {
//объект не найден, поэтому ничего с ним делать нельзя
}
Как это можно реализовать?
PS. Документацию читал, но не нашел. В описании метода this.wdgAt(<путь>, true) о том, что будет результатом при отсутствии объекта по указанному пути ничего не сказано.
|
Сообщение создано: 17. 11. 2018 [23:53]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
|
Что мешает попробовать — напечатать результат?
В ДемоБД масса примеров!
В JavaScript это просто if(obj) { ... }
Тут NULL нет и не нужно, вместо него false, 0, "", зависимо от типа.
И EVAL, как специфика для DAQ и SCADA.
Learn, learn and learn better than work, work and work.
|
Сообщение создано: 19. 11. 2018 [10:33]
|
kantv
Антон Калюк
Создатель темы
Зарегистрирован(а) с: 29.11.2016
Сообщения: 17
|
Добрый день.
Спасибо за ответ, к сожалению, несмотря на Ваши рекомендации у меня пока ничего путного не вышло.
Постараюсь описать что я делал.
Я создал новый пустой проект test в котором создал единственную пустую страницу root (/wlb_originals/wdg_Box) и поместил на нее единственное текстовое поле Text1 (/wlb_originals/wdg_Text). Также в структуру проекта добавил пустые логические контейнеры section1 и section2. В коде страницы root разместил следующий скрипт:
Text1_text = "start"; //выводим надпись, чтобы четко понимать, что скрипт запускался и данная строка выполнялась
obj = this.wdgAt(this.attr("path") + "pg_section1", true); // получаем объект по указанному пути
Text1_text = "obj=" + obj; //пытаемся вывести текстовое представление полученного объекта
В данном случае объект прекрасно находится по указанному пути, и в результате в тестовом поле получаем:
obj=<TCntrNodeObj path="/subUI/mod_VCAEngine/ses_test/pg_root/pg_section1/"/>
то есть видим, что получили объект типа TCntrNodeObj, который расположен в системе по пути /subUI/mod_VCAEngine/ses_test/pg_root/pg_section1/, что понятно и полностью соответствует документации.
После этого я пробовал изменить путь получаемого объекта так, чтобы он указывал на несуществующий объект, чтобы посмотреть что будет результатом в таком случае, то есть скрипт изменился на
Text1_text = "start";
obj = this.wdgAt(this.attr("path") + "pg_section3", true); // получаем объект по несуществующему пути
Text1_text = "obj=" + obj;
как можно видеть во второй строке указано "pg_section3", а такого объекта в проекте нет. При запуске проекта ожидалось, что в переменной obj мы получим некое значение, которое должно соответствовать не найденному объекту, например это мог бы быть 0, пустая строка "", false или что-то еще. Но при запуске проекта в текстовом поле я получаю значение
Text
то есть значение данного поля по умолчанию. Получается, что скрипт даже не начинал работу, поскольку если бы выполнилась хотя бы первая строка скрипта мы должны были получить как минимум сообщение
start
Поэтому у меня появились следующие вопросы:
1. при указании в методе wdgAt() пути к несуществующему объекту скрипт вообще запускался?
2. если скрипт запускался, то почему мы не получили в текстовом поле хотя бы сообщения start?
3. как все же можно проверить наличие объекта по указанному пути?
Буду Вам очень признателен за ответы.
|
Сообщение создано: 19. 11. 2018 [11:03]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
|
Ну да, я этой функцией не особо и пользуюсь, на стороне пользовательского программирования, и она имеет такую проблему — возврат пустого-некорректного объекта вместо false, что останавливает вычисление.
Исправил, сборки будут скорее всего только в конце недели.
Используйте глобальную nodeAt(), которая не имеет такой проблемы, если срочно нужно!
Learn, learn and learn better than work, work and work.
|
Сообщение создано: 19. 11. 2018 [13:48]
|
kantv
Антон Калюк
Создатель темы
Зарегистрирован(а) с: 29.11.2016
Сообщения: 17
|
Понятно. Спасибо.
Пробую реализовать то же самое, но через метод nodeAt(). Теперь при вызове метода с путем к несуществующему объекту получаю 0, то есть все корректно и можно выполнять сравнение полученного результата с 0 и таким образом проверять существует объект по указанному пути или нет.
Но столкнулся с другой проблемой. Надеюсь, что я что-то не понял и Вы мне подскажите.
Изменил скрипт из первого поста до следующего вида
Text1_text = "start"; //выводим надпись, чтобы четко понимать, что скрипт запускался и данная строка выполнялась
path = this.nodePath("", true) + "pg_section1"; //задаем путь к искомому объекту
obj = this.nodeAt(path, "/"); // получаем объект по указанному пути
Text1_text = "obj=" + obj; //выводим текстовое представление полученного объекта
во второй строке задается путь к логическому контейнеру, который вложен в корневую страницу проекта. В результате получаю следующее сообщение в Text1:
obj=<TCntrNodeObj path="/sub_UI/mod_VCAEngine/ses_test/pg_root/"/>
указанный в результате путь соответствует самой странице root, но не вложенному в нее логическому контейнеру section1. Насколько я понимаю, это значит, что в результате выполнения метода nodeAt() получили объект самой страницы root, а не логического контейнера section1.
Напомню, что изначально (первый пост) при использовании метода this.wgdAt() и указании верного пути к логическому контейнеру section1 в результате получалось:
obj=<TCntrNodeObj path="/sub_UI/mod_VCAEngine/ses_test/pg_root/pg_section1"/>
то есть выводимый путь четко указывал, что полученный объект это именно логический контейнер section1.
Я пробовал задавать путь в методе nodeAt() разными способами, но получить объект соответствующий именно логическому контейнеру section1 не получилось - всегда получал именно объект самой страницы root, а дочерних объектов получить не удалось.
Подскажите, что я делаю не так? Почему через метод nodeAt() не удается получить дочерние объекты корневой страницы?
PS. Документацию на метод nodeAt() читал вот здесь (http://wiki.oscada.org/Doc/OpisanieProgrammy), но не помогло.
[Сообщение редактировалось 1 раз(а), в последний раз 19.11.2018 в 13:49.]
|
Сообщение создано: 19. 11. 2018 [15:42]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
|
Две ошибки, какие читайте в документации!
path = this.nodePath() + "pg_1/pg_mn/pg_1";
obj = SYS.nodeAt(path);
this.messInfo("obj="+obj);
2018-11-19T15:41:33 1[/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/] obj=<TCntrNodeObj path="/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/pg_1/pg_mn/pg_1/"/>
2018-11-19T15:41:33 1[/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/] obj=<TCntrNodeObj path="/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/pg_1/pg_mn/pg_1/"/>
2018-11-19T15:41:34 1[/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/] obj=<TCntrNodeObj path="/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/pg_1/pg_mn/pg_1/"/>
2018-11-19T15:41:34 1[/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/] obj=<TCntrNodeObj path="/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/pg_1/pg_mn/pg_1/"/>
2018-11-19T15:41:34 1[/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/] obj=<TCntrNodeObj path="/sub_UI/mod_VCAEngine/ses_AGLKS/pg_so/pg_1/pg_mn/pg_1/"/>
Learn, learn and learn better than work, work and work.
|
Сообщение создано: 19. 11. 2018 [17:03]
|
kantv
Антон Калюк
Создатель темы
Зарегистрирован(а) с: 29.11.2016
Сообщения: 17
|
Спасибо за подсказку.
Для тех кто будет потом читать данную тему:
Заработало вот в таком варианте
Text1_text = "start"; //выводим надпись, чтобы четко понимать, что скрипт запускался и данная строка выполнялась
path = this.nodePath("", true) + "pg_section1"; //задаем путь к искомому объекту
obj = SYS.nodeAt(path); // получаем объект по указанному пути
Text1_text = "obj=" + obj; //выводим текстовое представление полученного объекта
В результате в текстовом поле получаем:
obj=<TCntrNodeObj path="/sub_UI/mod_VCAEngine/ses_test/pg_root/pg_section1/"/>
то есть получили объект pg_section1, который является дочерним для корневой страницы root. А если указать путь к несуществующему объекту, то SYS.nodeAt() вернет 0, сигнализируя таким образом, что объект по указанному пути не существует, что и требовалось.
|
Сообщение создано: 19. 11. 2018 [17:24]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
|
"kantv" wrote:
Для тех кто будет потом читать данную тему:
Заработало вот в таком варианте
А если ещё подумать то можно записать проще:
Text1_text = "start"; //выводим надпись, чтобы четко понимать, что скрипт запускался и данная строка выполнялась
obj = this.nodeAt("pg_section1"); // получаем объект по указанному пути
Text1_text = "obj=" + obj; //выводим текстовое представление полученного объекта
Learn, learn and learn better than work, work and work.
|
|
|