2013-05-12 127 views
4

由于以下问题,我现在被困在一起了几天。我的用例是我有一个拥有数百万个地址的数据库。从网络应用程序中,我想搜索它们,显示退出列表,然后显示有关单个地址的信息。一个重要目标是将搜索条件表示为URL的一部分。这样用户可以回到以前的搜索,甚至通过操纵URL来构建搜索。所以,我想有一个URL是这样的:带有动态过滤器的搜索路线/搜索标准

http://localhost/#/searchresults?lastname=king&firstname=stephen&city=somecity 

我不管理设置路由器来处理这些类型的网址。所有的尝试都以死胡同结束。如何使ember进入/ searchresults路线,以及如何使用RESTAdapter让它转发这些过滤条件?

回答

5

基础上的从直观的像素转向我想出了以下解决方案。

我构建了以下网址: http://somedomain.com/#/searchresults/?lastname=king&firstname=stephen&city=somecity

如何网址是池莉构建在此不再赘述的方式。在我的情况下,我用表单和一些事件处理程序使用我自己的视图。

把我弄得工作看起来像这样的代码:

App.Router.map(function() { 
    this.resource("searchresults", { path: '/searchresults/:dynamic' }); 
}); 

App.SearchresultsRoute = Ember.Route.extend((function() { 
    var deserializeQueryString = function (queryString) { 
     if(queryString.charAt(0) === "?") 
      queryString = queryString.substr(1); 

     var vars = queryString.split('&'), 
      i = 0, length = vars.length, 
      outputObj = {}; 

     for (; i < length; i++) { 
      var pair = vars[i].split('='); 
      outputObj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); 
     } 
     return outputObj; 
    }; 

    return { 
      model: function(param) { 
      var paramObj = deserializeQueryString(param.dynamic); 
      return App.Searchresult.find(paramObj); 
      } 
     }; 
    })() 
); 

App.Store = DS.Store.extend({ 
    revision: 12, 
    adapter: DS.RESTAdapter.create({ 
     namespace: 'api' 
    }) 
}); 

App.Searchresult = DS.Model.extend({ 
    lastname: DS.attr('string'), 
    firstname: DS.attr('string'), 
    street: DS.attr('string'), 
    hno: DS.attr('string'), 
    zip: DS.attr('string'), 
    city: DS.attr('string'), 
    country: DS.attr('string'), 
    birthdate: DS.attr('string') 
}); 

这产生一个HTTP GET请求,我的REST API:

{"searchresults": 
    [{"id":"2367507","lastname":"King","firstname":"Stephen","street":"Mainstreet.","hno":"21" ...}, 
    {"id":"3222409","lastname":"King","firstname":"Stephen","street":"Broadway","hno":"35" ...} 
    ]} 

http://somedomain.com/api/searchresults?lastname=king&firstname=stephen&city=somecity 

我的REST API与响应

然后用这个模板将其显示出来:

<h2>Searchresults</h2> 
<table> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th>Street/Hno</th> 
      <th>City</th> 
      <th>Birthyear</th> 
     </tr> 
    </thead> 
    <tbody> 
    {{#each item in controller}} 
     <tr> 
      <td>{{item.firstname}} {{item.lastname}}</td> 
      <td>{{item.street}} {{item.hno}}</td> 
      <td>{{item.zip}} {{item.city}}</td> 
      <td>{{item.birthdate}}</td> 
     </tr> 
    {{/each}} 
    </tbody> 
</table> 

如果有人发现更优雅的方式,那不需要使用自定义的解串器,我会很乐意更新解决方案。 (另一个)丹尼尔提供的答案暗示http://somedomain.com/#/searchresults/king/stephen/somecity不适合我的情况,因为在我需要的解决方案中,我有超过10个不同的搜索标准/过滤器。用户通常只选择填写其中的一些。

这个例子上烬数据修订的基础:12和灰烬1.0.0-RC.3

0

我有网址,其中包含有关新闻页码的信息,并根据它发送和ajax调用。我的路由器是这样的:

App.Router.map(function() { 
    this.resource('news', { path: '/n/:id' }); 
}); 

但你也可以不喜欢它:

App.Router.map(function() { 
     this.resource('searchresults', { path: '/searchresults/:lastname/:firstname/:city' }); 
    }); 

以及您的网址应该是这样的:

http://localhost/#/searchresults/king/stephen/somecity 

然后你只需指定:

App.SearchresultsRoute = Em.Route.extend({ 
    model: function(params) { 
     var lastname = params.lastname; 
      var firstname = params.firstname; 
      var city = params.city; 
      someFunction(lastname, firstname, city); 
    } 
}); 

我希望我的回答有帮助y OU。祝你今天愉快!

+0

这可能会实现。但是,我的实际模型和我的搜索表单比较复杂。用户可以选择10个以上的字段(名字,姓名,街道,住宅号码,出生日期,...)。为了进行搜索,用户通常仅为这些字段中的几个提供内容。如果我要这样构造URL,他们总是必须明确地包含所有的标准,即使这些字段中的大部分都是空的:即http:// localhost /#/ searchresults/king/stephen //////// somecity。我不喜欢,这个网址不能“显示”某个位置代表什么。即它不可见,那个位置3代表街道。 – Daniel 2013-05-12 11:37:28

3

要利用烬数据,你可以这样做。 假设你有一个这样的模式:

App.SearchResult = DS.Model.extend({ 
    firstName: DS.attr('string'), 
    lastName: DS.attr('string'), 
    city: DS.attr('string') 
}); 

,然后你在你的路线模型挂钩是做你这样做:

App.SearchResultsRoute = Ember.Route.extend({ 
    model: function(params){ 
    return App.SearchResult.find({firstName:params.firstName,lastName:params.lastName,city:params.city}) 
    } 
}); 

这样的RESTAdapter会自动发出像你的请求。例如:

http://localhost/#/searchresults?firstname=xxx&lastname=xxx&city=xxx 

希望它可以帮助

+0

我试过这个,但是我得到这个错误:“未捕获的错误:没有路由与URL匹配'/ searchresults?name = anna'”。我的App.Router.map包含“his.resource('searchresults');” – Daniel 2013-05-12 11:28:10

+0

我以为你已经是动态细分市场了:'this.resource('searchresults',{path:'/ searchresults /:dynamic'});' – intuitivepixel 2013-05-12 11:40:11

+0

太棒了。这样我就能使它工作。将会有两个区别:网址现在是...... ts /?firstname = x ...在“?”之前带有短划线。 2.在SearchResultsRou​​te中传递给model()的参数并不像您的示例中所示的那样结构化。相反,我得到{dynamic:“?name = anna”}。所以另外,我将不得不反序列化查询字符串。我可以轻松处理。 – Daniel 2013-05-12 12:47:18