2012-11-11 109 views
3

所以我想做的是做一個HTTP獲取請求,然後用響應更新視圖。由於某種原因,它無法正常工作。這是我的。流星異步代碼更新視圖

我一直在關注這個要點:https://gist.github.com/3443021

在客戶端:

Template.search.items = function() { 
    var query = Session.get("query"); 
    console.log(query); 
    var resp; 
    Meteor.call("search", query, function(err, res) { 
     console.log(res); 
     //return res; 
     return [1,2,4]; 
    }); 
}; 

在服務器上:

Meteor.methods({ 
    search: function(query) { 
     var fut = new Future(); 
     // var onComplete = fut.resolver(); 

     Meteor.http.get("http://localhost:4242/autocomplete/"+query, function(err, res) { 
      var content = res.content; 
      var resp = JSON.parse(content); 
      console.log(resp); 
      fut.ret(resp) 
     }); 
     return fut.wait(); 
    } 
}); 

並且在這個視圖我做:

<template name="search"> 
<h1>test</h1> 
<table class="table table-hover"> 
<tbody> 
    {{#each items}} 
    {{> searchItem}} 
    {{/each}} 
</tbody> 

看來如果我從Meteor.call函數內部返回,沒有任何東西被髮送到視圖。有任何想法嗎?

回答

2

在客戶端,沒有光纖或任何東西,Meteor.call是異步的,模板將不會從幫助程序返回值。

documentation

在客戶端,如果不傳遞一個回調,你是不是末節裏,調用將返回undefined,你將沒有辦法獲得的返回值方法。這是因爲客戶端沒有光纖,所以實際上沒有任何方法可以阻止遠程執行方法。

您可以使用rendered回調在模板更改後手動操作模板。

Template.search.rendered = function() { 
    var query = Session.get("query"), 
     table = this.find('.table-container'); 
    console.log(query); 
    var resp; 
    Meteor.call("search", query, function(err, res) { 
    console.log(res); 
    table.innerHTML = Template.search_items(res); // render the table with another template 
    }); 
} 
1

我正在使用此解決方案,更復雜,但沒有會話。 但更好的方法是在背景上使用一些模型(模板可以用模型調用 - 帶有{{#with}} handlebar)。 我將只顯示這個原則...

Template.search.items= function() { 

//todo: move this 'Promiss' class to shared code. 
var Promiss = function (iniValue) { 

    var self = this; 

    //-- Reactive Property Result, setter & getter 
    this._result = iniValue; 
    this._resultDeps = new Deps.Dependency; 
    this.setResult = function(value) { 

     self._result = value; 
     self._resultDeps.changed(); 
     //at this moment template will be recomputed, because we have 
     // changed '_resultDeps' 
    }; 

    this.getResult = function() { 
     Deps.depend(self._resultDeps); 
     return self._result; 
    }; 

    }; //end of Promiss class 


//after recompution we take saved result 
if (this._backupSearchPromiss) 
    return this._backupSearchPromiss; 

var promiss = new Promiss([/*ini value untill server response*/]); 
this._backupSearchPromiss= promiss; 

//call server.. 
Meteor.call("search", function (err, result) { 
    //todo: handle error 
    promiss.setResult(result); 

}); 
return promiss; 

};//end of template method 

,而在HTML:

{{#each search.getResult}} 
    {{>searchItem}} 
{{/each}}