简体   繁体   English

Ember 2.0如何使模板和路由互相对话?

[英]Ember 2.0 How can I make template and route talk to each other?

I am teaching myself Ember-cli and am trying to build a simple application, which fetches results when user searches for a term. 我正在自学Ember-cli,并尝试构建一个简单的应用程序,该应用程序在用户搜索术语时获取结果。 I am getting the ajax result just fine, but I am not sure how to "pass" that to the template 我得到的ajax结果很好,但是我不确定如何将其“传递”给模板

This is my hbs code now /app/templates/product-search.hbs: 这是我现在的hbs代码/app/templates/product-search.hbs:

The search field works just fine. 搜索字段可以正常工作。

<p>*Is 'xyz' by deafult. </p>
{{input class="form-control" id="search-string" type="text" value=this.search-string placeholder="Search by Product"}}
<button type="button" {{action "searchByProduct" this.search-string}}>Lookup Product</button>

<ul>

    {{#each result as |item|}}
        <li>Product Name: {{item.prodName}}</li>
    {{else}}
            Sorry, nobody is here.
    {{/each}}
</ul>

This is the route file: /app/routes/product-search.js 这是路由文件:/app/routes/product-search.js

import Ember from 'ember';

export default Ember.Route.extend({  
    actions: {
        searchByProduct:  function(qString) {
            var term = qString || 'xyz';
            var fetchURL = 'http://some-api.com/search?callback=JSON_CALLBACK&limit=10&term='+term;
            var result = Ember.Object.create({

            });
            return $.ajax({
              url: fetchURL,
              dataType: 'jsonp'
            }).then(function (response) {
                result.set('content', response.results);
                result = result.get('content');
                console.log("Search Result In Then Promise of Model: ");
                console.log(result); //I get an array of objects (screenshot included)
                return result; 
            });
        }
    }
});

Console o/p: 控制台o / p:

在此处输入图片说明

and a single object looks like this: 一个对象看起来像这样:

0: Object
productId: 471744
productName: "xyz"
productViewUrl: "https://someapi.com/us/product/xyz/id471744?uo=4"
imageUrl30: "http://.../source/30x30bb.jpg"
imageUrl60: "http://.../source/60x60bb.jpg"
imageUrl100: "http://.../source/100x100bb.jpg"
collectionId: 700049951
collectionName: "XYZ Collection"
collectionPrice: 9.99
country: "USA"
currency: "USD"
wrapperType: "track"
......
__proto__: Object

So I do see results in my result object but I am still not able to display it in my template. 因此,我的确在result对象中看到了结果,但仍无法在模板中显示它。 Maybe am not looping over the right object? 也许没有遍历正确的对象? Or do I need to pass something else? 还是我需要通过其他内容? I have no idea what am missing. 我不知道缺少什么。 Any help is appreciated, I've been stuck with this for a couple hours now. 感谢您的帮助,我已经坚持了几个小时。

1) You route model hook must return the promise. 1)你的路由model钩子必须返回承诺。

Breakdown of what's happening in your code: 细分您的代码中正在发生的事情:

export default Ember.Route.extend({
    model: function(params){
        var result = [];              // Create an array
        $.ajax({                      // Start an AJAX request...
          success: function(response){
            result.set('content', response.results);
           }
        });                           // ...but discard the promise
        console.log(result);          // log the array (still empty)
        return result;                // return the array (still empty)
    }
});                                   // much later, the AJAX call completes but
                                      // Ember does not care.

Ember gets an empty array. 灰烬得到一个空数组。 As it is not a promise, it assumes it can use it immediately, so it sets it as model and renders the template immediately. 由于这不是一个承诺,因此它假定可以立即使用它,因此将其设置为model并立即呈现模板。

Fixing it: 解决方法:

export default Ember.Route.extend({
    model: function(params){
        var term = 'random';
        var fetchURL = 'http://some-api.com/search?callback=JSON_CALLBACK&limit=10&term='+term;
        return $.ajax({
          url: fetchURL,
          dataType: 'jsonp'
        }).then(function (data) {
            return data.results;   // do whatever processing you have to do
        });
    }
});

This way, you directly return the promise to Ember. 这样,您可以直接将承诺退还给Ember。 Seeing that, Ember knows it must wait for the promise to resolve. 看到这一点,Ember知道它必须等待诺言解决。 When the AJAX call succeeds, the data is passed to the then handler, which returns the actual data to use. 当AJAX调用成功时,数据将传递到then处理程序, then处理程序返回要使用的实际数据。 In turn, Ember gets that data and sets it for use by the template. 反过来,Ember获取该数据并进行设置以供模板使用。

You definitely should read a bit about promises . 您绝对应该阅读有关诺言的文章 (Beware though that jQuery's “promises” are not standard). (请注意,尽管jQuery的“承诺”不是标准的)。

By the way, I see you are loading ember-data . 顺便说一句,我看到您正在加载ember-data You should definitely use it instead of $.ajax to load resources. 您绝对应该使用它而不是$.ajax来加载资源。 That's what it's for, and it does a much better job of streamlining data models into your Ember workflow. 这就是它的用途,并且在将数据模型简化为Ember工作流程中做得更好。

2) Unless you override it, the data returned by the model hook will be named model in the template. 2)除非您重写它,否则model挂钩返回的数据将在模板中命名为model

So just replace results with model in your template and you'll be fine: {{#each model as |item|}} 因此,只需将results替换为模板中的model ,就可以了: {{#each model as |item|}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM