我刚开始学习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上的场地的编号
yokota-ab-japan
4c806eabd92ea093ea2e3872
当地方路线被击中时,我通过调用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对象并返回它:
linkTo
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当用户单击指向它的链接时,它不会被调用,但是在此路由上刷新页面时,它会被调用。
PlaceRoute
根据PeepCode Ember.js的截屏视频(在视频中约12:25处显示),它说“控制器很少调用数据,路由对象处理该请求”,所以我认为将Ajax调用放入该位置是正确的路线(我在网上看到了很多不同的教程,但是由于Peepcode向Ember.js的创建者进行了咨询,所以我将其作为主要的学习资源)。
如果这不正确,或者可以做得更好,请告诉我。
模型挂钩上的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。
{{linkTo}}
{{#linkTo 'place' place}} {{place.name}} {{/linkTo}}
setupController hook