在jQuery中,我們常會傳入匿名函數當作參數,供後續某些事件發生時呼叫。例如:

$("#btnOK").click(function() { alert("OK"); });

那麼,我們由Javascript端呼叫Silverlight的Method時,是否也能傳入匿名函數,請Silverlight在稍後呼叫? 做法很簡單,用ScriptObject承接傳入的匿名Function,接著呼叫ScriptObject.InvokeSelf就可以囉!

如果想多一點,InvokeSelf時並不會檢查ScriptObject本身是否為Javascript Function,若否,則會發生InvalidOperationException。針對傳入參數非Function的問題,我們可以用try { ... } catch (InvalidOperationException ex) { ... }的寫法來解決。

在以下範例中,則再積極一些,在傳入參數時就檢查! 利用HmltPage.Window.Eval,我們可在Javascript端建立共用的jssk_IsFunction(obj)用來檢測某物件是否為Function,接著以HtmlPage.Window.Invoke將傳入參數送給jssk_IsFunction檢測。

程式碼如下:

    public class JavascriptSidekick
    {
        public bool IsFunction(ScriptObject obj)
        {
            string script = @"
if (window.jssk_IsFunction == undefined) 
    window.jssk_IsFunction = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Function]';
    }
";
            HtmlPage.Window.Eval(script);
            return (bool)HtmlPage.Window.Invoke("jssk_IsFunction", obj);
        }
        [ScriptableMember]
        public void CallbackTest(ScriptObject cb)
        {
            if (IsFunction(cb))
            {
                Thread.Sleep(5000);
                cb.InvokeSelf("Darkthread");
            }
            else
                HtmlPage.Window.Alert(cb.Invoke("toString").ToString() +
                    " is not a function!");
        }
    }

Javascript端則是:

function onSilverlightLoad(sender, args) {
    var slCtl = sender.getHost();
    var jssk = slCtl.Content.JavascriptSidekick;
    jssk.CallbackTest(function(name) { 
        alert("Hello, " + name); 
    });
    jssk.CallbackTest({ name:"Blah" });
    jssk.CallbackTest(["AAA"]);
}

其中傳入物件及字串陣列時,分別會得到[object Object] is not a function!、AAA is not a function!


Comments

Be the first to post a comment

Post a comment