javascript - Meteor JS : How do I insert a document into a collection, 但仅在客户端?

标签 javascript collections meteor

我是 Meteor 的新手,正在构建一个简单的应用程序来学习该框架。我正在构建的应用程序允许您在小猫的图像上放置文字。

期望的行为是这样的:

用户在小猫的任意位置单击,然后会出现一个 contenteditable 元素,让用户输入文本。在元素外部单击可保存该元素,它会保留在原位。

我遇到的问题:

如果我用该应用程序打开了两个浏览器窗口,并且我在一个窗口中单击了一只小猫,那么两个窗口中都会出现一个空白字段。理想情况下,空白字段只会出现在我单击的窗口上。一旦保存了一个单词,那么在两个窗口中都应该可见。

我的问题:

有没有办法只在客户端将文档插入到集合中,然后稍后使用upsert将文档添加到服务器端集合?

这是我尝试过的:

我创建了一个仅存在于客户端的 stub 方法,用于插入文档。这样做的问题是,当我单击图像时,会出现一瞬间的空白字段,然后再次消失。

代码如下:

image-tags.js

if (Meteor.isClient) {
  var isEditing;

  Template.image.image_source = function () {
    return "http://placekitten.com/g/800/600";
  };

  Template.tag.rendered = function(){
    var tag = this.find('.tag');
    if (isEditing && !tag.innerText) {
      tag.focus();
    }
  }

  Template.image.events({
    'click img' : function (e) {
      if (isEditing) {
        isEditing = false;
      } else {
        isEditing = true;
        var mouseX = e.offsetX;
        var mouseY = e.offsetY;

        // Tags.insert({x:mouseX, y:mouseY});

        // Insert tag on the client-side only.
        // Upsert later when the field is not empty.
        Meteor.call('insertTag', {x:mouseX, y:mouseY});
      }
    },

    'click .tag' : function (e) {
      isEditing = true;
    },

    'blur .tag' : function (e) {
      var currentTagId = this._id;
      var text = e.target.innerText;

      if(text) {
        Tags.upsert(currentTagId, {$set: {name: text}});
      } else {
        Tags.remove(currentTagId);
      }
    }
  });

  Template.image.helpers({
    tags: function() {
      return Tags.find();
    }
  });

  // Define methods for the collections
  Meteor.methods({
    insertTag: function(attr) {
      Tags.insert({x:attr.x, y:attr.y});
    }
  });
}

// Collections
Tags = new Meteor.Collection('tags');

image-tags.html

<head>
  <title>Image Tagger</title>
</head>

<body>
  {{> image}}
</body>

<template name="image">
  <figure>
    <img src="{{image_source}}" />
    <figcaption class="tags">
        {{#each tags}}
          {{> tag}}
        {{/each}}
      </figcaption>
  </figure>
</template>


<template name="tag">
  <div class="tag" contenteditable style="left: {{x}}px; top: {{y}}px;">
    {{name}}
  </div>
</template>

最佳答案

您应该将临时标签(可能还有您的 isEditing var)存储在 Session 中:

Session.set("isEditing", true);
Session.set("newTag", {x:mouseX, y:mouseY});

您还可以通过在初始化时传递 null 而不是集合名称来创建本地集合。但是,Session 应该适用于您正在做的事情。查看leaderboard举个例子。

编辑:

<figcaption class="tags">
  {{#each tags}}
    {{> tag}}
  {{/each}}
  {{#with newTag}}
    {{> tag}}
  {{/with}}
</figcaption>

Template.image.newTag = function() {
  return Session.get("newTag");
}

关于javascript - Meteor JS : How do I insert a document into a collection, 但仅在客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20823587/

相关文章:

java - 根据输入参数获取Java列表

Java 8 列表到 map 的转换

python - 在 Python 中合并时间戳列表

javascript - JS 文件未加载第一页加载?

javascript - 我想在注册成功时显示弹出消息,如果注册失败,则在同一页面上重定向时显示失败消息

javascript - 如何使用 Jasmine 自定义记者发布失败的规范列表以发布到松弛?

meteor 数据订阅策略

javascript - Chart.js 仅在按下 f12 后显示

Meteor:我怎么知道数据库什么时候准备好?

javascript - 获取meteor中的数据库版本