УкраїнськаEnglishmRussian
Вход/Новый
В теме нет новых постов

[BugFixed] Проверка наличия ссылки на объект (не NULL)


Автор Сообщение
Сообщение создано: 17. 11. 2018 [23:28]
kantv
Антон Калюк
Создатель темы
Зарегистрирован(а) с: 29.11.2016
Сообщения: 17
Доброго времени суток.
Подскажите, что вернет метод виджета this.wdgAt(<путь>, true), если по указанному пути ничего нет, или другими словами по указанному пути нет объектов?
Я хотел бы после получения результата как то проверить его на валидность, то есть проверить, что в результате был получен какой-то объект. В других языках, например в C# для пустых ссылок на объект есть встроенное значение NULL, сравнивая с которым можно произвести проверку на наличие объекта перед тем как пытаться вызывать его методы. Есть ли какой-то аналог NULL в JavaLikeCalk у OpenSCADA?

То есть как можно реализовать примерно такую конструкцию?
JAVASCRIPT
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 разместил следующий скрипт:
JAVASCRIPT
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/, что понятно и полностью соответствует документации.

После этого я пробовал изменить путь получаемого объекта так, чтобы он указывал на несуществующий объект, чтобы посмотреть что будет результатом в таком случае, то есть скрипт изменился на
JAVASCRIPT
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 и таким образом проверять существует объект по указанному пути или нет.

Но столкнулся с другой проблемой. Надеюсь, что я что-то не понял и Вы мне подскажите.

Изменил скрипт из первого поста до следующего вида
JAVASCRIPT
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
Две ошибки, какие читайте в документации!
JAVASCRIPT
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
Спасибо за подсказку.

Для тех кто будет потом читать данную тему:
Заработало вот в таком варианте
JAVASCRIPT
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:

Для тех кто будет потом читать данную тему:
Заработало вот в таком варианте

А если ещё подумать то можно записать проще:
JAVASCRIPT
Text1_text = "start"; //выводим надпись, чтобы четко понимать, что скрипт запускался и данная строка выполнялась
obj = this.nodeAt("pg_section1"); // получаем объект по указанному пути
Text1_text = "obj=" + obj; //выводим текстовое представление полученного объекта


Learn, learn and learn better than work, work and work.



20297