为什么不是我的灰烬。调用js路径模型?

时间:2020-12-31 20:14:38

I just started learning Ember.js (bought the PeepCode screencast), and am learning quite smoothly from it, but ran into a problem when trying to write my first Ember app.

我刚开始学烬。js(买了PeepCode的screencast),我学得很顺利,但是在写我的第一个Ember应用时遇到了问题。

Here's the (nested) route mapping:

这里是(嵌套的)路由映射:

App.Router.map(function () {
    this.resource('bases', { path: '/' }, function () {
        this.resource('base', { path: ':base_id' }, function () {
            this.resource('places', function () {
                this.resource('place', { path: ':place_id' });
            });
        });
    });
});

This allows urls like this: domain.com/#/yokota-ab-japan/places/4c806eabd92ea093ea2e3872

这允许像这样的url: domain.com/#/yokota-ab-japan/places/4c806eabd92ea093ea2e3872

yokota-ab-japan is the id of a base (an Air Force base in Japan) 4c806eabd92ea093ea2e3872 is the id of a venue on Foursquare

横田-日本是一个基地的id(日本的一个空军基地)4c806eabd92ea093ea2e3872是Foursquare上一个地点的id

When the places route is hit, I setup the data with a call to the foursquare api, iterate over the JSON to create an array of App.Place objects, and return that array.

单击places路由时,我使用对foursquare api的调用来设置数据,遍历JSON以创建App.Place对象数组,并返回该数组。

App.PlacesRoute = Ember.Route.extend({
    model: function () {
        var placesData = Ember.A();
        $.getJSON('https://api.foursquare.com/v2/venues/search?ll=35.744771,139.349456&query=ramen&client_id=nnn&client_secret=nnn&v=20120101',
            function (data) {
                $.each(data.response.venues, function (i, venues) {
                    placesData.addObject(App.Place.create({ id: venues.id, name: venues.name, lat: venues.location.lat, lng: venues.location.lng }));
                });
            });

        return placesData;
    }
});

That seems to work well. I display the placesData array using this template:

看起来效果不错。我使用此模板显示placesData数组:

<script type="text/x-handlebars" data-template-name="places">
    <div>
        {{#each place in controller}}
            {{#linkTo 'place' place}}
                {{place.name}}
            {{/linkTo}}
        {{/each}}
    </div>

    {{outlet}}
</script>

The linkTo links to the individual place, where I want to show more details about a place. Here's the route I setup to pull data about the single place, populate a single App.Place object, and return it:

链接到单个地方的链接,在那里我想展示关于一个地方的更多细节。下面是我设置的路径,用于提取关于单个位置的数据,填充一个App.Place对象,然后返回:

App.PlaceRoute = Ember.Route.extend({
    model: function (params) {
        console.log('place route called');

        var place;
        $.getJSON('https://api.foursquare.com/v2/venues/' + params.place_id + '?client_id=nnn&client_secret=nnn',
            function (data) {
                var v = data.response.venue;
                place = App.Place.create({ id: v.id, name: v.name, lat: v.location.lat, lng: v.location.lng });
            });

        return place;
    }
});

My problem is, PlaceRoute doesn't get called when the user clicks a link to it, but it does get called when the page is refreshed on this route.

我的问题是,PlaceRoute在用户单击链接时不会被调用,但在此路由上刷新页面时它会被调用。

According to the PeepCode Ember.js screencast (at ~12:25 into the video) it states that "controllers rarely ever make calls to data, route objects handle that", so I think I'm correct in putting my ajax calls in the routes (I've seen so many differing tutorials online, but since Peepcode consulted with the Ember.js creators, I went with it as my primary learning source).

根据PeepCode烬。js screencast(视频约12:25)说“控制器很少对数据进行调用,路由对象会处理这些数据”,所以我认为我把ajax调用放到路由中是正确的(我在网上见过很多不同的教程,但是自从Peepcode咨询了Ember之后。js创建者,我把它作为我的主要学习来源)。

If this isn't correct, or could be done better, please let me know.

如果这不是正确的,或者可以做得更好,请让我知道。

3 个解决方案

#1


49  

Ember Documentation on the model hook:

关于模型挂钩的烬文档:

"A hook you can implement to convert the URL into the model for this route."

“您可以实现一个钩子,将URL转换为此路径的模型。”

This explains why the model hook is just called on page refresh. But this confuses a lot of people :-). So, this is not the right hook in this case. I think you should use the setupController hook for this case. Try this:

这解释了为什么在页面刷新时调用模型钩子。但这让很多人困惑:-)。所以,在这种情况下,这不是正确的钩。我想你应该用setupController钩子来解决这个问题。试试这个:

App.PlaceRoute = Ember.Route.extend({
    setupController: function (controller, model) {
        console.log('place route called');

        var place;
        $.getJSON('https://api.foursquare.com/v2/venues/' + model.get('place_id') + '?client_id=nnn&client_secret=nnn',
            function (data) {
                var v = data.response.venue;
                place = App.Place.create({ id: v.id, name: v.name, lat: v.location.lat, lng: v.location.lng });
            });

        controller.set("model", place);
    }
});

Additional 2 cents from myself: Why is the model hook just executed, when the app is entered via URL/direct browser navigation?

另外2分来自我自己:为什么当应用程序通过URL/direct浏览器导航进入时,模型钩子刚刚被执行?

Ember has the assumption, that you do not necessarily make a call to the model hook, if you use {{linkTo}}. In your places template you use {{#linkTo 'place' place}} {{place.name}} {{/linkTo}}. You are passing a place object to your route. Ember assumes that this is the same object, that you would get when executing your model hook. So from Embers View there is no need to call the model hook. So if you want to perform retrieval logic even when you use linkTo, use the setupController hook.

Ember有一个假设,如果您使用{{linkTo}},您并不一定要调用模型钩子。在places模板中,您使用{{#linkTo 'place} {place.name} {/ /linkTo}}}。您正在向路径传递一个place对象。Ember假设这是同一个对象,在执行模型钩子时将会得到这个对象。因此,从Embers的观点来看,没有必要调用模型钩子。所以如果你想执行检索逻辑,即使你使用linkTo,也要使用setupController钩子。

#2


16  

FYI:

仅供参考:

You could use the model hook for this kind of thing, just pass the id instead of the object:

你可以用模型钩子来做这种事情,只是传递id而不是对象:

{{#link-to 'place' place.id}}
    {{place.name}}
{{/link-to}}

As Ember no longer knows which object is related to given id, Ember is forced to reload the data (so Ember calls the model hook).

当Ember不再知道哪个对象与给定的id相关时,Ember将*重新加载数据(因此Ember调用模型钩子)。

#3


3  

Based on mavilein's answer, but shorter and suitable for Ember CLI with Ember Data...

基于mavilein的答案,但更短,适合于Ember CLI和Ember数据…

import Ember from 'ember';

export default Ember.Route.extend({
  setupController: function( controller, model ) {
    controller.set( "model", this.store.fetch( 'place', model.id ) );
  },
});

Also note that the fetch method is only available from Ember Data 1.0.0-beta.12.

还要注意的是,fetch方法只能从Ember数据1.0.0-beta.12中获得。

http://emberjs.com/api/data/classes/DS.Store.html#method_fetch

http://emberjs.com/api/data/classes/DS.Store.html method_fetch

#1


49  

Ember Documentation on the model hook:

关于模型挂钩的烬文档:

"A hook you can implement to convert the URL into the model for this route."

“您可以实现一个钩子,将URL转换为此路径的模型。”

This explains why the model hook is just called on page refresh. But this confuses a lot of people :-). So, this is not the right hook in this case. I think you should use the setupController hook for this case. Try this:

这解释了为什么在页面刷新时调用模型钩子。但这让很多人困惑:-)。所以,在这种情况下,这不是正确的钩。我想你应该用setupController钩子来解决这个问题。试试这个:

App.PlaceRoute = Ember.Route.extend({
    setupController: function (controller, model) {
        console.log('place route called');

        var place;
        $.getJSON('https://api.foursquare.com/v2/venues/' + model.get('place_id') + '?client_id=nnn&client_secret=nnn',
            function (data) {
                var v = data.response.venue;
                place = App.Place.create({ id: v.id, name: v.name, lat: v.location.lat, lng: v.location.lng });
            });

        controller.set("model", place);
    }
});

Additional 2 cents from myself: Why is the model hook just executed, when the app is entered via URL/direct browser navigation?

另外2分来自我自己:为什么当应用程序通过URL/direct浏览器导航进入时,模型钩子刚刚被执行?

Ember has the assumption, that you do not necessarily make a call to the model hook, if you use {{linkTo}}. In your places template you use {{#linkTo 'place' place}} {{place.name}} {{/linkTo}}. You are passing a place object to your route. Ember assumes that this is the same object, that you would get when executing your model hook. So from Embers View there is no need to call the model hook. So if you want to perform retrieval logic even when you use linkTo, use the setupController hook.

Ember有一个假设,如果您使用{{linkTo}},您并不一定要调用模型钩子。在places模板中,您使用{{#linkTo 'place} {place.name} {/ /linkTo}}}。您正在向路径传递一个place对象。Ember假设这是同一个对象,在执行模型钩子时将会得到这个对象。因此,从Embers的观点来看,没有必要调用模型钩子。所以如果你想执行检索逻辑,即使你使用linkTo,也要使用setupController钩子。

#2


16  

FYI:

仅供参考:

You could use the model hook for this kind of thing, just pass the id instead of the object:

你可以用模型钩子来做这种事情,只是传递id而不是对象:

{{#link-to 'place' place.id}}
    {{place.name}}
{{/link-to}}

As Ember no longer knows which object is related to given id, Ember is forced to reload the data (so Ember calls the model hook).

当Ember不再知道哪个对象与给定的id相关时,Ember将*重新加载数据(因此Ember调用模型钩子)。

#3


3  

Based on mavilein's answer, but shorter and suitable for Ember CLI with Ember Data...

基于mavilein的答案,但更短,适合于Ember CLI和Ember数据…

import Ember from 'ember';

export default Ember.Route.extend({
  setupController: function( controller, model ) {
    controller.set( "model", this.store.fetch( 'place', model.id ) );
  },
});

Also note that the fetch method is only available from Ember Data 1.0.0-beta.12.

还要注意的是,fetch方法只能从Ember数据1.0.0-beta.12中获得。

http://emberjs.com/api/data/classes/DS.Store.html#method_fetch

http://emberjs.com/api/data/classes/DS.Store.html method_fetch