javascript 为什么我的 ember.js 路由模型没有被调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15678817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 01:40:20  来源:igfitidea点击:

Why isn't my ember.js route model being called?

javascriptajaxjsonmodel-view-controllerember.js

提问by Chaddeus

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.

我刚开始学习 Ember.js(购买了 PeepCode 截屏视频),并且从中学习得非常顺利,但是在尝试编写我的第一个 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

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

yokota-ab-japanis the id of a base (an Air Force base in Japan) 4c806eabd92ea093ea2e3872is the id of a venue on Foursquare

yokota-ab-japan是一个基地(日本的一个空军基地) 4c806eabd92ea093ea2e3872的 id 是 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 linkTolinks 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:

linkTo指向单个地点的链接,我想在其中显示有关某个地点的更多详细信息。这是我设置的用于提取有关单个地点的数据、填充单个 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, PlaceRoutedoesn'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 Ember.js 截屏视频(视频中的约 12:25),它指出“控制器很少调用数据,路由对象会处理它”,所以我认为我将 ajax 调用放在路线(我在网上看过很多不同的教程,但自从 Peepcode 咨询了 Ember.js 的创建者,我把它作为我的主要学习来源)。

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

如果这不正确,或者可以做得更好,请告诉我。

回答by mavilein

Ember Documentation on the model hook:

模型钩子上的 Ember 文档:

"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/直接浏览器导航输入应用程序时,为什么模型钩子刚刚执行?

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}}. 在您的场所模板中,您使用{{#linkTo 'place' place}} {{place.name}} {{/linkTo}}. 您正在将一个地点对象传递给您的路线。Ember 假设这是同一个对象,您在执行模型挂钩时会得到它。所以从 Embers View 中不需要调用模型钩子。因此,如果您想在使用时执行检索逻辑linkTo,请使用setupController hook.

回答by Jacob van Lingen

Force Ember to use the model hook; just pass the id instead of the object:

强制 Ember 使用模型钩子;只需传递 id 而不是对象:

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

As Ember no longer knows which object is related to given id, Ember will call the model hook (and so the data will be loaded from the server).

由于 Ember 不再知道哪个对象与给定的 id 相关,Ember 将调用模型钩子(因此数据将从服务器加载)。

回答by Keith Broughton

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

基于 mavilein 的回答,但更短且适用于带有 Ember Data 的 Ember CLI ......

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 Data 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