如何知道插入Meteor.JS的MongoDB集合是否成功(在模板内)

How to know if an insertion was successfull in a MongoDB Collection with Meteor.JS (inside the Template)

本文关键字:成功 是否 集合 插入 何知道 Meteor JS MongoDB      更新时间:2023-09-26

情况

让我们把这个问题分解为一个简单的待办事项列表,其中的条目列在一个''li:中

//main.html
<ul>
{{ #each listEntries }}
  <li class="item">
   {{ title }}
  </li>
{{ /each }}
</ul>

服务器端:

//main.js
TodoCollection = new Mongo.Collection('todo_collection');

现在我从客户端的控制台手动调用:

TodoCollection.insert({title: 'My first entry'});

到目前为止一切都很好

现在是流星。JS异步工作,这意味着在不知道数据库插入是否成功的情况下,客户端中所做的更改也会立即对DOM产生影响。如果没有,DOM元素将再次被删除(因此首先meter插入新的<li>,然后如果插入失败,它将再次删除它(。

你怎么能从流星那里得到一些东西实际上来自数据库的信息?

我需要什么:

//main.html
<ul>
{{ #each listEntries }}
  <li class="item">
   {{ title }}
   {{ #if isInDatabase }}
     - i am actually stored!
   {{ /if }}
  </li>
{{ /each }}
</ul>

您可以使用集合的insert方法的回调。调用回调时会出现错误(如果没有,则为null(和存储在数据库中的对象Id

下面你可以看到测试这个的代码:

html

<head>
  <title>simple</title>
</head>
<body>
  <h1>Welcome to Meteor!</h1>
  {{>test}}
</body>
<template name="test">
  <ul>
      {{#each item in list}}
      <li>{{item.name}}</li>
      {{/each}}
  </ul>
  {{#if insertResult}}
  <div class="insert_result">{{insertResult}}</div>
  {{/if}}
  {{#if insertError}}
  <div class="insert_error">{{insertError}}</div>
  {{/if}}
  <form>
      <input type="text" name="name" />
      <input type="submit" value="Add" />
  </form>
</template>

Javascript:

import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
collection = new Mongo.Collection('collection');
if (Meteor.isClient) {
    Template.test.onCreated(function () {
        this.insertResult = new ReactiveVar();
        this.insertError = new ReactiveVar();
    });
    Template.test.helpers({
        list() {
            return collection.find();
        },
        insertResult() {
            return Template.instance().insertResult.get();
        },
    });
    Template.test.events({
        'submit form'(event, instance) {
            event.preventDefault();
            collection.insert({
                name: event.target.name.value
            },function(err,result) {
                if (err) {
                    instance.insertError.set(err);
                    instance.insertResult.set(null);
                } else {
                    instance.insertResult.set(result);
                    instance.insertError.set(null);
                }
            });
        },
    });
}

正如您在前面的回答中所看到的,在Meteor中,要知道是什么导致了反应式更新是非常麻烦的。

我建议一种不同的方法:不要在客户端插入。制作一个Meteor.call()到执行插入的服务器方法,然后让客户端进行反应更新。然后您总是确保您在屏幕上看到的内容实际上在数据库中。

我想我自己找到了最琐碎的解决方案:在服务器端添加一个钩子,该钩子将使用obj.onCreated = new Date();添加创建日期,这有助于识别它来自服务器,因为它在客户端上不存在。

  {{#each item}}
    {{ #if item.onCreated }}
      <li class="success-db">{{name}}</li>
    {{ else }}
      <li class="pending-db">{{name}}</li>
    {{ /if }}
  {{/each}}

(如果您发现这个答案与Meteor.JS的工作方式相矛盾,请毫不犹豫地改进它(

如果你想显示标题存在的数据,那么你可以这样写代码。

<ul>
{{ #each listEntries }}
  <li class="item">
   {{ title }}
   {{ #if title }}
     - i am actually stored!
   {{ /if }}
  </li>
{{ /each }}
</ul>