在我目前的meteor.js项目中,用户可以创建项目并向其添加数据节点。我使用D3在力图中显示节点。当他们从图表中单击特定节点时,必须突出显示侧面板中的相应文本。为此,我需要选择跟踪节点。但是,我不想存储"选择"数据库中的字段。
我现在使用此数据转换添加所选字段 -
/lib/routes.js
Router.route('/project/:code', {
name: 'projectPage',
data: function() {
return {
project: Projects.findOne({code : this.params.code}),
nodes: Nodes.find({project: this.params.code}, {transform: function (doc) {
doc.selected = false;
return doc;
}})
}
}
});
模板是/client/templates/projectPage.html
<template name="projectPage">
<div class="project-page page">
<h3>{{project.title}}</h3>
<p>{{project.summary}}</p>
<div class="work-area">
<div class="map-space">
{{> nodeDisplay nodes=nodes}}
</div>
<div class="type-space">
{{> typeDisplay nodes=nodes}}
</div>
</div>
</div>
</template>
<template name="nodeDisplay">
<div id="svgdiv"></div>
</template>
<template name="typeDisplay">
{{#each nodesData}}
<p>{{text}}</p>
<br/>
{{/each}}
</template>
点击事件处理/client/js/projects.js
Template.nodeDisplay.events({
'click .node':function(event, template){
/*remove previous selection*/
d3.selectAll('.selected circle').attr("r",32);
d3.selectAll('.selected').each(
function(d){
d.fixed = false;
d3.select(this)
.classed('selected', false);
}
);
/*add new selections*/
d3.select(event.currentTarget)
.classed("selected", true)
d3.selectAll('.selected circle').attr("r",40);
var selected_id = $(event.currentTarget).data("id");
Nodes.update(selected_id.toString(), {$set: {selected: true}});
}
});
但是,这会更新数据库以包含&#34;选择&#34;领域。 有没有更好的方法来保持反应性?
答案 0 :(得分:2)
流星方式是使用会话变量和辅助函数。
所以而不是
Nodes.update(selected_id.toString(), {$set: {selected: true}});
使用
Session.set("selected_node", this._id);
和Template.typeDisplay.helpers中的一个帮助帮助
isNodeSelected: function() {
if(Session.get("selected_node") === this._id) {
return "selected"
}
}
显示每个节点的模板中的(此代码假定您要通过应用类名&#39;选择&#39;)来选择typeDisplay中的相应文本:
<template name="typeDisplay">
{{#each nodesData}}
<p class="{{isNodeSelected}}">{{text}}</p>
<br/>
{{/each}}
</template>