2013-04-09 32 views
1

我有一个silverlight用户控件,我有一个文本框和一个按钮。这个Silverlight页面中可以有多个这些用户控件。从一个复杂的javascript函数返回一个值返回到silverlight用户控件

当点击按钮时,我想启动一个javascript函数,它调用jquery弹出窗口,通过iframe在相同的应用程序中打开另一个页面。在该页面中,用户进行搜索并将数据一直传递给silverlight用户控件,并且需要用文本框填充该数据。

在silverlight中使用HtmlPage Invoke方法我可以调用javascript函数。 在这个JavaScript内,我也可以调用jquery mobile popup。但是,我无法从该功能返回搜索词。函数立即返回空字符串。我用setTimeout和延迟方法,但仍然没有成功。 在弹出窗口中,当用户完成搜索单词并关闭窗口时,该弹出功能调用名为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'); 
} 
+0

我觉得我发现的一个问题是jquery mobile弹出窗口本身是异步方法。所以即使弹出窗口打开,该功能的其余部分仍然继续执行。我将不得不查看是否可以将此弹出窗口设置为模式窗口,并阻止对该函数的进一步处理,直到此窗口关闭。 – bobsov534 2013-04-09 19:09:56

+0

重要的是要知道主页面和弹出页面的位置 - 特别是关于它们的域。这决定了应用程序架构。此外,你说“用户进行搜索”,但不清楚究竟搜索了什么或进行搜索的地方 - 客户端还是服务器端?目前还不清楚搜索结果是什么? – 2013-04-09 20:26:32

+0

这是在.net中完成的基本搜索页面。生成的id传递给“setSearchWord”的父页面函数。这一切都有效,只是因为弹出窗体是异步的,到搜索结果返回并设置时,函数已经执行。除非变量'searchWord'被确定为非空,否则我需要一些帮助来防止函数返回。 – bobsov534 2013-04-09 20:45:24

回答

0
$(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') 
     } 
    }); 
0

Bobsov,我可以给你提前一个可行的办法,但没有比这更好的恐怕:

,因为它不能返回一个值直接,openPopUp需要返回一个承诺,这将在解决问题时产生所需的值。对于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环境)非常自信。 Promise需要进行某种翻译。

经过一番研究,我找到了一个名为SilverQuery的东西,它通过一个托管的代码桥,结合了jQuery的强大功能和表现力,以及Silverlight运行时和jQuery JavaScript库的托管代码桥。

不幸的是,我不能再进一步,因为我无法在这台计算机上运行测试,并且找不到证据表明Silverquery将桥接jQuery的延迟/承诺。这些可能是在编写SilverQuery之后引入的(SilverQuery下载的日期为2009年9月,当时jQuery约为1.3或1.4 IIRC,并且尚未包含$ .Deferred API)。

也许有人知道如果SilverQuery是可行的,或者更好,更简单的方法。

+0

这是你提供的很棒的帮助。我非常感激。这给了我弹药从一个完全不同的角度来看待它。我会研究SilverQuery,看看这里是否有可能的解决方案。 – bobsov534 2013-04-10 15:51:20

0

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

现在您可以通过另一种方式实现相同的结果。我假设你想阻止线程,因为你不想让用户在父页面上做任何事情?为什么不关闭父页面上的所有内容,直到弹出窗口关闭?您可以在弹出框下方的整个页面上创建一个浮动DIV,以便拦截所有鼠标事件并不做任何事情。

+0

实际上,弹出框足够大,不允许用户访问父页面。问题是我想函数调用等待弹出框关闭,然后继续其余的代码执行。相反,它只是继续执行。即使我放置了20秒的延迟,Silverlight用户控件也立即得到空值。出于某种原因,它甚至不希望延迟20秒。 – bobsov534 2013-04-10 19:43:25

0

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

希望这是有道理的。基本上,我在托管代码中创建了另一种方法,并使用[ScriptableMember]对其进行了装饰,并将其展示给了JavaScript。这让我可以从javascript调用这个方法。问题解决了!!

谢谢甜菜根和奥马尔为您的意见和建议,让我去。