Titanium mvc - 调用函数并等待结果

时间:2011-12-11 01:34:55

标签: javascript iphone model-view-controller titanium titanium-mobile

我目前正在制作我的第一款Titanium iPhone应用程序。

在我得到的模型中:

(function() {   
    main.model = {};

    main.model.getAlbums = function(_args) {

        var loader = Titanium.Network.createHTTPClient();  
        loader.open("GET", "http://someurl.json"); 

        // Runs the function when the data is ready for us to process 
        loader.onload = function() { 
            // Evaluate the JSON  
            var albums = eval('('+this.responseText+')');  
            //alert(albums.length);
            return albums;
        }; 

        // Send the HTTP request  
        loader.send();  

    };

})();

我在以下视图中调用此函数:

(function() {

    main.ui.createAlbumsWindow = function(_args) {

        var albumsWindow = Titanium.UI.createWindow({  
            title:'Albums',
            backgroundColor:'#000'
        });

        var albums = main.model.getAlbums();

        alert(albums);

        return albumsWindow;
    };
})();

然而,似乎对模型的调用(使用HTTP获取某些数据)不等待响应。在我执行警报的视图中,它还没有收到模型中的数据。我如何以最佳实践方式做到这一点?

提前致谢

5 个答案:

答案 0 :(得分:6)

行,

像这样,

function foo(arg1, callback){
     arg1 += 10;
     ....
     ... Your web service code
     ....
     callback(arg1); // you can have your response instead of arg1
}

you will call this function like this,

foo (arg1, function(returnedParameter){
     alert(returnedParameter); // here you will get your response which was returned in   above function using this line .... callback(arg1);
});

所以这里arg1是参数(简单参数,如整数,字符串等......),第二个参数是你的回调函数。

干杯。

答案 1 :(得分:3)

您需要的是对Web服务的同步调用,以便它等待您从服务获得响应。

要在java脚本中实现此目的,您必须将回调函数作为参数传递并在回调函数中获取返回值,而不是通过return语句返回值。

实际上你正在使用的编码风格对我来说是新的,因为我使用不同的编码风格。

但主要的是你必须使用回调函数来检索值而不是return语句。尝试这个,如果你仍然面临问题而不是告诉我,我会试着举个例子。

答案 2 :(得分:0)

像零解释的回调方式很好地解释了,但你也可以尝试用事件处理它。

(function() {

    main.ui.createAlbumsWindow = function(_args) {

        var albumsWindow = Titanium.UI.createWindow({  
            title:'Albums',
            backgroundColor:'#000'
        });

        var status = new object(), // eventlistener
        got_a_valid_result = false;

        // catch result
        status.addEventListener('gotResult',function(e){
          alert(e.result);
          got_a_valid_result = true;
        });           

        // catch error
        status.addEventListener('error',function(e){
          alert("error occured: "+e.errorcode);
          git_a_valid_result = true;
        });

        var albums = main.model.getAlbums(status);

        // wait for result
        while (!got_a_valid_result){};
        return albumsWindow;
    };
})();

您的模型可能类似

main.model.getAlbums = function(status) {

        var loader = Titanium.Network.createHTTPClient();  
        loader.open("GET", "http://someurl.json"); 

        loader.onload = function() { 
            var albums = eval('('+this.responseText+')');  

            status.fireEvent('gotResult',{result:albums});
            return albums;
        }; 

        loader.onerror = function(e){
            status.fireEvent('error',{errorcode:"an error occured"});
        };

        // Send the HTTP request  
        loader.send();  

    };

答案 3 :(得分:0)

正如建议一样,尝试使用JSON.parse而不是eval,因为使用eval会涉及风险,因为它运行所有的javascript代码。

答案 4 :(得分:0)

我认为Zero发布的解决方案可能更适合内存管理,但我并不完全确定。如果您执行了eventListener,请注意以下事项 (见https://wiki.appcelerator.org/display/guides/Managing+Memory+and+Finding+Leaks

function doSomething(_event) {
    var foo = bar;
}
// adding this event listener causes a memory leak
// as references remain valid as long as the app is running
Ti.App.addEventListener('bad:idea', doSomething);

// you can plug this leak by removing the event listener, for example when the window is closed
thisWindow.addEventListener('close', function() {
// to remove an event listener, you must use the exact same function signature
// as when the listener was added
Ti.App.removeEventListener('bad:idea', doSomething);
});