【发布时间】:2016-10-07 18:21:42
【问题描述】:
简介:
_id: Pe0t3K8GG8,
videos: [
{id:'HdaZ8rDAmy', url:'VIDURL', rank: 2},
{id:'22vZ8mj9my', url:'VIDURL2', rank: 0},
{id:'8hyTlk8H^6', url:'VIDURL3', rank: 1},
]
个人资料与视频列表一起显示。我有一个拖放,它使用服务器方法更新视频排名。
1) 数据库在 Drop 时正确更新。
2) 对视频数组进行排序 - 我在 Profile Template 上声明了一个助手,并基于 SORT videos 数组声明了一个 >自定义比较功能。
Template.Profile.helpers({
'videosSorted': function(){
let videos = (this.videos);
let videosSorted = videos.sort(function(a, b) {
return parseFloat(a.rank) - parseFloat(b.rank);
});
return videosSorted;
}
});
问题:
A) 在 Blaze 中,{{#each videosSorted}} 不会被动更新。
如果我 F5 刷新然后我可以看到新订单。
我认为问题在于我提供的 videosSorted 不会更新数据库中文档的更改。
如何使 videosSorted 具有响应性?
更新:
所有相关代码: Iron Router Controller - 我订阅并设置布局的数据上下文
ProfileController = RouteController.extend({
subscriptions: function() {
this.subscribe('profile',this.params.slug).wait();
},
data: function () {
//getting the data from the subscribed collection
return Profiles.findOne({'slug':this.params.slug});
},
})
出版:
Meteor.publish('profile', function (slug) {
const profile = Profiles.find({"slug":slug});
if(profile){
return profile;
}
this.ready();
});
个人资料 HTML 模板:
<template name="Profile">
<ul class="sortlist">
{{#each videosSorted}}
{{> Video}}
{{/each}}
</ul>
</template>
我正在使用 mrt:jquery-ui - 可排序功能
Template.Profile.onRendered(function () {
thisTemplate = this;
this.$('.sortlist').sortable({
stop: function(e, ui) {
el = ui.item.get(0);
before = ui.item.prev().get(0);
after = ui.item.next().get(0);
if(!before) {
newRank = Blaze.getData(after).rank - 1
} else if(!after) {
newRank = Blaze.getData(before).rank + 1
}
else {
newRank = (Blaze.getData(after).rank +
Blaze.getData(before).rank) / 2
}
let queryData = {
_id: thisTemplate.data._id, //the id of the profile record
videos_objId: Blaze.getData(el).objId, //the id of the sub document to update
new_rank: newRank //the new rank to give it
};
//Update the sub document using a server side call for validation + security
Meteor.call("updateVideoPosition", queryData, function (error, result) {
if(!result){
console.log("Not updated");
}
else{
console.log("successfully updated Individual's Video Position")
}
});
}
})
});
最后是进行更新的 Meteor 方法
'updateVideoPosition': function (queryData){
let result = Individuals.update(
{_id: queryData._id, 'videos.objId': queryData.videos_objId },
{ $set:{ 'videos.$.rank' : queryData.new_rank } }
)
return result;
}
注意:
正如我所提到的 - 数据库正确更新 - 如果我有一个隐身窗口打开到同一页面 - 我会重新看到视频(神奇!)切换到新顺序。
架构
const ProfileSchema = new SimpleSchema({
name:{
type: String,
}
videos: {
type: [Object],
optional:true,
},
'videos.$.url':{
type:String,
},
'videos.$.rank':{
type:Number,
decimal:true,
optional:true,
autoform: {
type: "hidden",
}
},
'videos.$.subCollectionName':{
type:String,
optional:true,
autoform: {
type: "hidden",
}
},
'videos.$.objId':{
type:String,
optional:true,
autoform: {
type: "hidden",
}
}
});
【问题讨论】:
-
如果你这样做
let videos = this.videos.slice(),它会起作用吗? -
您的收藏是如何定义的?
-
所有助手都是响应式的并且依赖于
currentData()。所以,你的助手应该被动地工作。可能您在以前的模板级别上失去了反应能力。能把视频文档相关的js/html代码全部贴出来吗? -
@Tdm 我已经更新了问题,在 Update 标题下
-
好的。诊断。在对 mongo 进行异步更新之前调用 videosSorted 助手。方法返回后如何调用该助手手动运行。
标签: javascript arrays sorting meteor reactive-programming