从有点复杂的javascript函数返回值到silverlight用户控件

Returning a value from a bit complex javascript function back to silverlight user control

本文关键字:返回值 silverlight 用户 控件 函数 javascript 复杂      更新时间:2023-09-26

我有一个silverlight用户控件,我有一个文本框和一个按钮。在这个silverlight页面中可以有多个这样的用户控件。

当按钮被点击,我想启动一个javascript函数调用jquery弹出打开另一个页面在同一应用程序通过iframe。在那个页面中,用户进行搜索,数据需要一直传递到silverlight用户控件,文本框需要被填充。

使用HtmlPage调用方法在silverlight我能够调用javascript函数。在这个javascript我能够调用jquery移动弹出以及。但是,我无法从该函数返回搜索词。下面的函数立即返回空字符串。我已经使用了setTimeout和defer方法,但仍然没有成功。在弹出窗口中,当用户搜索完单词并关闭窗口时,该弹出函数调用父函数setSearchWord()。此功能在设置搜索词变量的页面中。

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'); 
}
$(document).on('tap', '.btnSelectWord', function(){
        if( typeof parent.setSearchWord === 'function'){
            parent.setSearchWord(selectedPointId)
        }else if (typeof window.opener.setSearchWord == 'function'){
            window.opener.setSearchWord(selectedPointId);
        }
        else {
            console.log('No function')
            alert('No callback in parent')
        }
    });

Bobsov,我可以给你一条可能的路,但恐怕没有比这更好的了:

由于不能直接返回值,因此openPopUp需要返回一个Promise,该Promise在解析时将产生所需的值。对于javascript/jQuery,这是相当微不足道的,虽然它确实涉及全局变量/函数由于你的页面/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运行时和jQuery JavaScript库。"

不幸的是,我不能再进一步,因为我不能在这台计算机上运行测试,也找不到证据表明Silverquery将弥合jQuery的deferred/Promises。这些很可能是在SilverQuery编写之后引入的(SilverQuery的下载日期是2009年9月,当时jQuery大约是1.3或1.4 IIRC,还没有包含$。延迟API)。

也许其他人知道SilverQuery是否可行,或者更好的是,是否有一个更简单的方法。

JS的弹出式函数都是异步的。他们不会等。没有办法让JS等待弹出窗口被关闭。

现在您可以用另一种方法获得相同的结果。我假设您想要阻塞线程,因为您不想让用户在父页面上做任何事情?为什么不禁用父页面上的所有内容,直到弹出窗口关闭?您可以在弹出窗口下方的整个页面上创建一个浮动DIV,它将拦截所有鼠标事件而不做任何事情。

我想为解决这个问题给自己一个'Pat'。我所做的是——我调用了上面相同的过程来启动弹出框,但是当setSearchWord函数,在弹出框中调用设置id时,我在silverlight托管代码中创建了一个暴露给javascript的方法,并在我传递变量和设置silverlight文本框的地方调用该方法。

希望这是有意义的。基本上,我在托管代码中创建了另一个方法,并通过使用[ScriptableMember]来修饰它,将其暴露给javascript。这允许我从javascript调用这个方法。问题解决了! !

感谢Beetroot和Omar的意见和建议,让我继续前进。