【问题标题】:Titanium mvc - call function and wait for resultTitanium mvc - 调用函数并等待结果
【发布时间】:2011-12-11 01:34:54
【问题描述】:

我目前正在制作我的第一个 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 获取一些数据)似乎没有等待响应。在我发出警报时的视图中,它还没有从模型接收到数据。如何以最佳实践方式做到这一点?

提前致谢

【问题讨论】:

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


    【解决方案1】:

    好的,

    类似的,

    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 是参数(简单的参数,如整数、字符串等),第二个参数是你的回调函数。

    干杯。

    【讨论】:

    • 这是一个很好的例子。在我的示例中,我试图打开一个模式,从用户那里收集一条信息,关闭模式,然后重新打开我的索引视图。我得到了正确的回调,但之后我的索引视图不会显示出来。我没有使用 modal.close() ,而是使用了 modal.hide() 这允许我的索引视图显示。希望这可以帮助某人
    【解决方案2】:

    您需要的是对网络服务的同步调用,这样它就会等到您从服务中得到响应。

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

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

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

    【讨论】:

    • 非常感谢您的回复。我一直在玩弄使用回调函数的想法。如果你能给我一个例子,那就太棒了——如果你不介意的话:)
    【解决方案3】:

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

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

    【讨论】:

    • 感谢分享。我从来没有想过这个。这个方法我也试试看。
    【解决方案4】:

    作为一个建议,尝试使用 JSON.parse 而不是 eval,因为使用 eval 存在风险,因为它运行所有 javascript 代码。

    【讨论】:

      【解决方案5】:

      我认为 The 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);
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-07
        • 2016-12-20
        • 1970-01-01
        • 2018-01-11
        • 1970-01-01
        • 2019-05-09
        • 1970-01-01
        相关资源
        最近更新 更多