小编典典

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

ajax

我刚开始学习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' });
            });
        });
    });
});

这样就可以使用以下网址:domain.com/#/yokota-ab-japan/places/4c806eabd92ea093ea2e3872

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

当地方路线被击中时,我通过调用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;
    }
});

看来运作良好。我使用以下模板显示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>

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

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

根据PeepCode
Ember.js的截屏视频(在视频中约12:25处显示),它说“控制器很少调用数据,路由对象处理该请求”,所以我认为将Ajax调用放入该位置是正确的路线(我在网上看到了很多不同的教程,但是由于Peepcode向Ember.js的创建者进行了咨询,所以我将其作为主要的学习资源)。

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


阅读 182

收藏
2020-07-26

共1个答案

小编典典

模型挂钩上的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);
    }
});

我额外支付2美分: 通过URL /直接浏览器导航输入应用程序后,为什么刚刚执行了模型挂钩?

Ember假设,如果使用,则不必调用模型挂钩{{linkTo}}。在场所模板中使用{{#linkTo 'place' place}} {{place.name}} {{/linkTo}}。您正在将地点对象传递到路线。 Ember假定这是执行模型挂钩时将得到的同一对象。
因此,从Embers View中无需调用模型挂钩。因此,即使您在使用时也要执行检索逻辑linkTo,请使用setupController hook

2020-07-26