流星铁路由器嵌套的路线 [英] meteor iron-router nested routes
问题描述
我有两个具有一对多关系的流星集合:建筑物和空间
在我的建筑物页面上,我想显示与建筑物有关的空间.
现在,我是这样做的:
buildingsRoute.coffee
BuildingController = RouteController.extend(template: "buildings")
Router.map ->
@route "building",
path: "/buildings/:_id"
waitOn: ->
subs.subscribe "allBuildings"
subs.subscribe "allSpaces"
data: ->
building: Buildings.findOne(@params._id)
spaces: Spaces.find({building_id: @params._id})
building.jade:
template(name="building")
+with building
.building
.page-header.position-relative
h1.inline #{name}
.row
.col-xs-12
+spacesList
template(name="spacesList")
.widgets
.row
h1 Spaces
+each spaces
.col-xs-12.col-sm-6
.widget-box.widget-color-purple
.widget-header
a(href="{{pathFor 'space'}}") #{name}
.widget-body
p Content here
这是不行的,我想是因为spacesList模板的数据上下文与铁路由器为构建而定义的上下文不同.
我可以用"+ each ../spaces"替换"+ each spaces",但这对我来说似乎不是一个非常通用的解决方案(如果我想在其他情况下使用我的spaceslist模板呢?)>
所以我试图像这样在模板助手中定义数据上下文:
Template.spacesList.helpers
spaces: Spaces.find({building_id: @params._id})
但是我收到错误消息:
Spaces is not defined.
所以我有点困惑.正确实现嵌套路由的流星方法是什么?
谢谢!
空间集合的定义:/models/space.coffee
@Spaces = new Meteor.Collection("spaces",
schema:
building_id:
type: String
label: "building_id"
max: 50
name:
type: String
label: "Name"
optional: true
max: 50
creation_date:
type: Date
label: "Creation date"
defaultValue: new Date()
)
出版物:/server/publications.coffee
# Buildings
Meteor.publish "allBuildings", ->
Buildings.find()
Meteor.publish "todayBuildings", ->
Buildings.find creation_date:
$gte: moment().startOf("day").toDate()
$lt: moment().add("days", 1).toDate()
# Publish a single item
Meteor.publish "singleBuilding", (id) ->
Buildings.find id
# Spaces
# Publish all items
Meteor.publish "allSpaces", ->
Spaces.find()
编辑2
经过一些研究,我终于想出了一个解决方案:
Template.spacesList.helpers
spaces: () ->
if Router._currentController.params._id
subs.subscribe "buildingSpaces", Router._currentController.params._id
Spaces.find()
else
subs.subscribe "allBuildings"
Spaces.find()
nbr_spaces: () ->
Spaces.find().count()
另附出版物:
# Publish all items for building
Meteor.publish "buildingSpaces", (building_id) ->
Spaces.find({building_id: building_id})
错误是:
- 空间定义未包装到函数中的事实
- 我用不太性感的Router._currentController.params._id代替了@ params._id,但是我找不到任何捷径.
我仍然不知道这是否是管理嵌套路由的最佳方法.
还有更好的建议吗?
在经历了许多不同的选择之后,我终于找到了一个铁路由器的选择,我以前没有注意到.这真是神奇.
使用yields可以更轻松地实现嵌套路由(至少有两个级别(我没有尝试更多级别)):
我的路线是这条路线:
Router.map ->
@route "buildingSpaces",
path: "/buildings/:_id/spaces"
template: "building"
yieldTemplates: {
'buildingSpaces': {to: "subTemplate"}
}
waitOn: ->
[subs.subscribe("allSpaces"),
subs.subscribe "allBuildings"]
data: ->
building: Buildings.findOne(@params._id)
spaces: Spaces.find({building_id: @params._id})
这些是我的模板:
template(name="building")
.animated.fadeIn
+with building
.building
.page-header.position-relative
h1.inline #{name}
.row
.col-xs-12
.tabbable
ul.nav.nav-tabs
li#menu-spaces(class="{{isActive 'buildingSpaces'}}")
a(href="{{pathFor 'buildingSpaces'}}") #{nbr_spaces} Spaces
li#menu-dashboards(class="{{isActive 'buildingDashboards'}}")
a(href="{{pathFor 'buildingDashboards'}}") Dashboards
.tab-content
+yield "subTemplate"
template(name="buildingSpaces")
.animated.fadeInDown
.page-header.position-relative
a.btn.btn-info.btn-sm#newSpaceButton
i.ace-icon.fa.fa-plus
| New space
.clearfix
+spacesList
template(name="spacesList")
.widgets
.row
+each spaces
.col-xs-12.col-sm-6
.widget-box.widget-color-purple
.widget-header
a(href="{{pathFor 'space'}}") #{name}
.widget-body
p Content here
+insertSpaceForm
最后,我有一个助手来管理菜单:
Handlebars.registerHelper "isActive", (template) ->
currentRoute = Router.current().route.name
if currentRoute and template is currentRoute then "active"
else ""
非常光滑.单击子菜单时,它仅加载子模板.这是我发现的最好的...
希望这对您有帮助...
I have two meteor collections with a one-to-many relationship: buildings and spaces
On my building page, I want to show the spaces related to the building.
For now, I did it this way:
buildingsRoute.coffee
BuildingController = RouteController.extend(template: "buildings")
Router.map ->
@route "building",
path: "/buildings/:_id"
waitOn: ->
subs.subscribe "allBuildings"
subs.subscribe "allSpaces"
data: ->
building: Buildings.findOne(@params._id)
spaces: Spaces.find({building_id: @params._id})
building.jade:
template(name="building")
+with building
.building
.page-header.position-relative
h1.inline #{name}
.row
.col-xs-12
+spacesList
template(name="spacesList")
.widgets
.row
h1 Spaces
+each spaces
.col-xs-12.col-sm-6
.widget-box.widget-color-purple
.widget-header
a(href="{{pathFor 'space'}}") #{name}
.widget-body
p Content here
This doesn't work as such, I guess because the data context of the spacesList template is not the same as the one defined by iron router for building.
I could replace "+each spaces" by "+each ../spaces" but this doesn't seem like a very generic solution to me (what if I want to use my spaceslist template in another context?)
So I tried to define the data context in template helpers like this:
Template.spacesList.helpers
spaces: Spaces.find({building_id: @params._id})
But I get the error message:
Spaces is not defined.
So I'm a bit confused. What is the meteor way to implement nested routes properly?
Thank you!
EDIT:
Definition of Spaces collection: /models/space.coffee
@Spaces = new Meteor.Collection("spaces",
schema:
building_id:
type: String
label: "building_id"
max: 50
name:
type: String
label: "Name"
optional: true
max: 50
creation_date:
type: Date
label: "Creation date"
defaultValue: new Date()
)
Publications: /server/publications.coffee
# Buildings
Meteor.publish "allBuildings", ->
Buildings.find()
Meteor.publish "todayBuildings", ->
Buildings.find creation_date:
$gte: moment().startOf("day").toDate()
$lt: moment().add("days", 1).toDate()
# Publish a single item
Meteor.publish "singleBuilding", (id) ->
Buildings.find id
# Spaces
# Publish all items
Meteor.publish "allSpaces", ->
Spaces.find()
EDIT 2
After some researches, I finally came up with a solution:
Template.spacesList.helpers
spaces: () ->
if Router._currentController.params._id
subs.subscribe "buildingSpaces", Router._currentController.params._id
Spaces.find()
else
subs.subscribe "allBuildings"
Spaces.find()
nbr_spaces: () ->
Spaces.find().count()
With an additional publication:
# Publish all items for building
Meteor.publish "buildingSpaces", (building_id) ->
Spaces.find({building_id: building_id})
The errors were:
- the fact that the space definition wasn't wrapped into a function
- the @params._id that I replaced by the not very sexy Router._currentController.params._id but I couldn't find any shortcut for this.
I still don't know whether this is the Meteor (best) way to manage nested routes...
Any better recommendation?
After going through a whole lot of different options, I finally found an option of iron-router that I didn't notice before. This makes the magic.
The implementation of nested routes (at least with two levels (I didn't try more levels)) becomes much easier with the use of yields:
My route is this one:
Router.map ->
@route "buildingSpaces",
path: "/buildings/:_id/spaces"
template: "building"
yieldTemplates: {
'buildingSpaces': {to: "subTemplate"}
}
waitOn: ->
[subs.subscribe("allSpaces"),
subs.subscribe "allBuildings"]
data: ->
building: Buildings.findOne(@params._id)
spaces: Spaces.find({building_id: @params._id})
These are my templates:
template(name="building")
.animated.fadeIn
+with building
.building
.page-header.position-relative
h1.inline #{name}
.row
.col-xs-12
.tabbable
ul.nav.nav-tabs
li#menu-spaces(class="{{isActive 'buildingSpaces'}}")
a(href="{{pathFor 'buildingSpaces'}}") #{nbr_spaces} Spaces
li#menu-dashboards(class="{{isActive 'buildingDashboards'}}")
a(href="{{pathFor 'buildingDashboards'}}") Dashboards
.tab-content
+yield "subTemplate"
template(name="buildingSpaces")
.animated.fadeInDown
.page-header.position-relative
a.btn.btn-info.btn-sm#newSpaceButton
i.ace-icon.fa.fa-plus
| New space
.clearfix
+spacesList
template(name="spacesList")
.widgets
.row
+each spaces
.col-xs-12.col-sm-6
.widget-box.widget-color-purple
.widget-header
a(href="{{pathFor 'space'}}") #{name}
.widget-body
p Content here
+insertSpaceForm
And finally, I have a helper to manage my menu:
Handlebars.registerHelper "isActive", (template) ->
currentRoute = Router.current().route.name
if currentRoute and template is currentRoute then "active"
else ""
It's quite slick. It loads only the subTemplate when clicking the submenu. It's the best I found...
Hope this helps...
这篇关于流星铁路由器嵌套的路线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!