4

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

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

我没有设法设置路由器来处理这些类型的 URL。所有的尝试都以死胡同告终。如何让 ember 进入 /searchresults 路由,以及如何让它使用 RESTAdapter 转发这些过滤条件?

4

3 回答 3

5

根据intuitivepixel的回答,我想出了以下解决方案。

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

该 URL 的构造方式在此不作描述。就我而言,我使用自己的视图和表单和一些事件处理程序。

我开始工作的代码如下所示:

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

这会生成一个对我的 REST API 的 HTTP GET 请求:

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

我的 REST API 响应:

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

然后使用此模板将其可视化:

<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 种不同的搜索标准/过滤器。用户通常只选择填写其中的几个。

此示例基于 ember-data 修订版:12 和 Ember 1.0.0-RC.3

于 2013-05-12T13:59:49.973 回答
3

要利用 ember 数据,您可以这样做。假设您有这样的模型:

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

然后在 Route 的模型钩子中执行以下操作:

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

希望能帮助到你

于 2013-05-12T11:17:57.580 回答
0

我有一个 URL,其中包含有关新闻页码的信息,并根据它发送和 ajax 调用。我的路由器看起来像:

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

但你也可以这样做:

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

您的 URL 如下所示:

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

希望我的回答对你有所帮助。祝你今天过得愉快!

于 2013-05-12T11:09:29.197 回答