Возврат значения из немного сложной функции javascript обратно в пользовательский элемент управления Silverlight

У меня есть пользовательский элемент управления Silverlight, где у меня есть текстовое поле и кнопка. На этой странице Silverlight может быть несколько таких пользовательских элементов управления.

Когда кнопка нажата, я хочу запустить функцию javascript, которая вызывает всплывающее окно jquery, чтобы открыть другую страницу в том же приложении через iframe. На этой странице пользователь выполняет поиск, и данные должны быть переданы вплоть до пользовательского элемента управления Silverlight, и текстовое поле должно быть заполнено этим.

Используя метод HtmlPage Invoke в Silverlight, я могу вызвать функцию javascript. В этом javascript я также могу вызвать всплывающее окно jquery mobile. Однако я не могу вернуть поисковое слово из этой функции вниз. Ниже функция немедленно возвращает пустую строку. Я использовал метод setTimeout и defer, но все равно безуспешно. Во всплывающем окне, когда пользователь заканчивает поиск слова и закрывает окно, эта всплывающая функция вызывает родительскую функцию с именем setSearchWord(). Эта функция находится на этой странице, которая устанавливает переменную searchWord.

var searchWord = '';

function calljquerymobilePopUp(){
$("$popupWin").popup('open'); 
  //what should I do here such that I can make sure 'searchWord' 
  //variable is not empty and return it to silverlight user control.
   return searchWord;
}

function setSearchWord(val){
  searchWord = val;     
  // I always get this value but its always too late. 
  // In silverlight user control, I end up getting empty string
  console.log(searchWord);

  $("$popupWin").popup('close'); 
}

person bobsov534    schedule 09.04.2013    source источник
comment
Я думаю, что одна проблема, которую я обнаружил, заключается в том, что мобильное всплывающее окно jquery само по себе является асинхронным методом. Таким образом, даже если всплывающее окно открыто, остальная часть функции продолжает выполняться. Мне нужно будет посмотреть, смогу ли я превратить это всплывающее окно в модальное окно и заблокировать дальнейшую обработку функции, пока это окно не будет закрыто.   -  person bobsov534    schedule 09.04.2013
comment
Важно знать, откуда обслуживаются главная и всплывающая страницы, особенно в отношении их доменов. Это определяет архитектуру приложения. Кроме того, вы говорите, что пользователь выполняет поиск, но неясно, что именно ищется или где выполняется поиск - на стороне клиента или на стороне сервера? Также неясно, каковы результаты поиска?   -  person Beetroot-Beetroot    schedule 10.04.2013
comment
это основная страница поиска, сделанная в .net. Результирующий идентификатор передается функции родительской страницы, которая называется setSearchWord. Все это работает, единственное, поскольку всплывающая форма асинхронна, к тому времени, когда результат поиска возвращается и устанавливается, функция уже выполняется. Мне нужна помощь в предотвращении возврата функции, если переменная 'searchWord' не определена как непустая.   -  person bobsov534    schedule 10.04.2013
comment
Просто чтобы посмотреть на это с другой точки зрения, если у меня есть окно подтверждения вместо всплывающего диалогового окна, вызывающая функция ждет, пока окно подтверждения завершит выполнение, а затем выполняет оставшуюся часть функции. Мне просто нужна аналогичная функциональность, используя всплывающее окно jquery mobile.   -  person bobsov534    schedule 10.04.2013
comment
Можете ли вы предоставить ссылку на документацию API для мобильного всплывающего окна jQuery, которое вы используете.   -  person Beetroot-Beetroot    schedule 10.04.2013
comment
api.jquerymobile.com/popup   -  person bobsov534    schedule 10.04.2013
comment
Я думаю, это зависит от того, как и где именно вызывается setSearchWord, но я не вижу этого кода.   -  person Beetroot-Beetroot    schedule 10.04.2013
comment
Я показал функцию jquery, которая вызывает функцию setSearchWord.   -  person bobsov534    schedule 10.04.2013


Ответы (3)


Бобсов, я могу дать вам возможный путь вперед, но, боюсь, не лучше этого:

Поскольку он не может вернуть значение напрямую, openPopUp должен вернуть обещание, которое при разрешении даст требуемое значение. Для javascript/jQuery это довольно тривиально, хотя включает глобальные vars/функции из-за архитектуры вашей страницы/iFrame.

Код будет примерно таким (в глобальном пространстве имен):

var searchDfrd;

function openPopUp() {
    $("$popupWin").popup('open');
    searchDfrd = $.Deferred().done(function(val) {
        console.log(val);
    });
    return searchDfrd.promise();
}

function setSearchWord(val) {
    searchDfrd.resolve(val);
    $("$popupWin").popup('close');
}

Теперь возникает проблема... openPopUp() возвращается не в javascript, а в Silverlight, откуда он был вызван с HtmlPage.Invoke.

Не имея особых знаний о Silverlight, я вполне уверенно могу сказать, что Silverlight не может напрямую обрабатывать jQuery Promise (это не среда javascript). Обещание должно быть подвергнуто некоторому переводу.

После небольшого исследования я наткнулся на нечто под названием SilverQuery, которое "сочетает в себе мощь и выразительность jQuery с производительностью .NET через мост управляемого кода между средой выполнения Silverlight и библиотекой JavaScript jQuery».

К сожалению, я не могу продолжать это, так как я не могу запускать тесты на этом компьютере и не могу найти доказательства того, что Silverquery будет соединять Deferreds/Promises jQuery. Вполне возможно, что они были введены после того, как был написан SilverQuery (загрузка SilverQuery датирована сентябрем 2009 года, когда jQuery был примерно на уровне 1.3 или 1.4 IIRC и еще не включал $.Deferred API).

Может быть, кто-то еще знает, является ли SilverQuery жизнеспособным или, что еще лучше, более простым подходом.

person Beetroot-Beetroot    schedule 10.04.2013
comment
Это потрясающая помощь, которую вы оказали. Я так благодарен за это. Это дает мне возможность взглянуть на это в совершенно другом измерении. Я посмотрю на SilverQuery и посмотрю, есть ли здесь возможное решение. - person bobsov534; 10.04.2013

Все всплывающие функции JS являются асинхронными. Они не будут ждать. На самом деле нет способа заставить JS ждать закрытия всплывающего окна.

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

person oazabir    schedule 10.04.2013
comment
На самом деле всплывающее окно достаточно велико, чтобы не разрешить пользователю доступ к родительской странице. Проблема в том, что я хотел бы вызвать функцию, чтобы дождаться закрытия всплывающего окна, а затем продолжить выполнение остальной части кода. Вместо этого он просто продолжает выполняться. Пользовательский элемент управления Silverlight немедленно получает нулевое значение, даже если я установил 20-секундную задержку. Почему-то не любит получать задержку даже на 20 секунд. - person bobsov534; 10.04.2013

Я хотел бы дать "Пэт" себе за решение этого вопроса. Что я сделал, так это то, что я вызвал тот же процесс, что и выше, чтобы запустить всплывающее окно, но когда функция setSearchWord, вызываемая внутри всплывающего окна для установки идентификатора, я создал метод в управляемом коде Silverlight, который подвергается воздействию javascript и вызывает этот метод, где я передаю переменная и установка текстового поля silverlight.

Надеюсь, это имеет смысл. По сути, я создал еще один метод в управляемом коде и представил его javascript, украсив его [ScriptableMember]. Это позволило мне вызвать этот метод из javascript. Задача решена!!

Спасибо Beetroot и Omar за ваши комментарии и предложения, которые поддерживали меня.

person bobsov534    schedule 11.04.2013