我正在与Meteor建立一个实时通知系统,但由于我以前从未这样做过,所以我当然会欺骗一些有用的东西。
我有一个Visual Studio
通知列表。我定义了一个事件,点击每个<ul>
包含的<a class="notif-link">
。
我的通知有ID,类型和其他一些我们不关心的内容。
<li>
...
notifications:
[
{id: 0, type: 0, img: null, link: "/profile"},
{id: 1, type: 1, img: null, link: "/profile"},
{id: 2, type: 2, img: null, link: "/profile"},
{id: 3, type: 3, img: null, link: "/profile"},
]
Template.navigation.events({
"click .notif-link": function(e, tmpl){
console.log(EJSON.stringify(this)); // print the verbosed notification object as shown above
var index = Meteor.user().profile.notifications.indexOf({id: this.id});
console.log(index); // always == -1
newNotifArray = Meteor.user().profile.notifications.splice(index, 1);
Meteor.users.update({_id: Meteor.userId()}, {$set: {'profile.notifications': newNotifArray}});
}
});
设置为notification.id
<a>
,这样我就可以识别数组中的通知,并在点击链接时将其删除。
问题是#id
总是给我-1。
我想问题是我不知道如何在一个对象数组上正常工作。
有人可以向我解释如何处理它吗?
谢谢你。
答案 0 :(得分:2)
问题是您试图在您定义的通知对象数组中找到您创建的新对象的索引:{id: this.id}
,这显然不包括它。
Array.IndexOf
当给定一个要搜索的对象时,会尝试在数组中找到相同的对象(内存中的指针),因此除非你有实际的对象,否则你无法真正使用它。
例如:notifications.indexOf({id: 0, type: 0, img: null, link: "/profile"})
,即使具有相同的值,也会返回-1,因为它是一个不同的对象。
我不熟悉Meteor,但在这种情况下有些库可以帮助你,例如下划线对数组和列表助手非常有用。 对于这种情况,您可以使用下划线的findWhere方法,如下所示:
_.notifications.findWhere({id: this.id})
这将返回数组中与您指定的属性匹配的实际对象,然后您可以使用实际对象Array.indexOf
来获取数组内对象的索引。
我确定要执行此操作的许多其他方法和库,取决于您已经使用的内容。 以下是一些不使用下划线的其他解决方案的链接:
使用纯Javascript地图 - indexOf method in an object array?
使用JQuery grep - Find object by id in an array of JavaScript objects
干杯。
答案 1 :(得分:1)
您正在寻找名为{id: 1}
的对象,但您的通知条目较大。它们也包含其他字段(不仅仅是ID字段)。您正在将标准JavaScript与MongoDB查询进行比较。
查看MongoDBs $pull操作。类似的东西:
Meteor.users.update({_id: Meteor.userId}, { $pull: {
'profile.notifications': { id: this.id },
}});
(我还没有对此代码进行测试,对id: this.id
查询不完全确定。)
将数据加载到内存中,然后将其修改然后再写回来可能看起来很直观(我首先做了同样的事情^^),但直接在数据库上操作是a)更有效率和b)更优雅。