为什么不调用我的ember.js路由模型?

Cha*_*eus 29 javascript ajax model-view-controller json ember.js

我刚刚开始学习Ember.js(购买了PeepCode截屏视频),并且从中学到了很顺利,但在尝试编写我的第一个Ember应用程序时遇到了问题.

这是(嵌套)路由映射:

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' });
            });
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

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

yokota-ab-japan是一个基地(在日本的空军基地) 4c806eabd92ea093ea2e3872的id是Foursquare上的场地的id

当命中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;
    }
});
Run Code Online (Sandbox Code Playgroud)

这似乎运作良好.我使用这个模板显示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>
Run Code Online (Sandbox Code Playgroud)

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;
    }
});
Run Code Online (Sandbox Code Playgroud)

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

根据PeepCode Ember.js的截屏视频(在视频中大约12:25),它表示"控制器很少会调用数据,路由对象会处理",所以我认为我把我的ajax调用放在了路线(我在网上看过很多不同的教程,但是自从Peepcode咨询了Ember.js的创作者之后,我就将它作为我的主要学习资源).

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

mav*_*ein 49

模型钩子上的Ember文档:

"您可以实现将URL转换为此路由的模型的钩子."

这解释了为什么只在页面刷新时调用模型钩子.但这让很多人感到困惑:-).所以,在这种情况下,这不是正确的钩子.我认为你应该在这种情况下使用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);
    }
});
Run Code Online (Sandbox Code Playgroud)

自己额外2美分:当通过URL /直接浏览器导航输入应用程序时,为什么模型钩子刚执行?

如果你使用的话,Ember假设你不一定要调用模型钩子{{linkTo}}.在您使用的场所模板中{{#linkTo 'place' place}} {{place.name}} {{/linkTo}}.您正在将一个位置对象传递给您的路线.Ember假设这是执行模型钩子时会得到的同一个对象.所以从Embers View中不需要调用模型钩子.因此,如果您想要在使用时执行检索逻辑linkTo,请使用setupController hook.

  • 这应该是基本的ember函数,我不知道为什么ember创建者认为所有数据都应该在master(list)页面中 - 它效率不高.这对于所有ember初学者来说都是非常困惑的. (2认同)

Jac*_*gen 17

供参考:

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

{{#link-to 'place' place.id}}
    {{place.name}}
{{/link-to}}
Run Code Online (Sandbox Code Playgroud)

由于Ember不再知道哪个对象与给定的id相关,因此Ember被迫重新加载数据(因此Ember调用模型钩子).