繁体   English   中英

Meteor JS:如何将文档插入集合中,但仅限于客户端?

[英]Meteor JS: How do I insert a document into a collection, but only on the client-side?

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

期望的行为是这样的:

用户单击小猫的任何位置,并且出现一个允许用户输入文本的可信元素。 单击元素外部可以保存元素,并保留在原位。

我遇到的问题:

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

我的问题:

有没有办法只在客户端insert文档插入到集合中,然后使用upsert将文档添加到servert-side集合?

这是我试过的:

我创建了一个存根方法,该方法仅存在于客户端以插入文档。 这个问题是,当我点击图像时,会出现一个空白字段,持续一秒钟,然后再次消失。

这是代码:

图像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');

图像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>

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

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

您还可以通过在初始化时传递null而不是集合名称来创建本地集合。 但是, Session应该适用于你正在做的事情。 查看排行榜以获取示例。

编辑:

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

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

如果仅在客户端创建集合,则在断开连接时可能会出现问题:新的文档将不会存储在服务器上。

在我看来,最好的方法是在文档中设置“已发布”或“编辑”或“状态”属性(带有值已发布/ eiditing / ...)。 然后你的发布方法应该返回:

  1. 当前用户的所有文档
  2. 所有文件“已发布”或未处于“编辑”状态

当用户创建文档时,它存储在服务器上但具有编辑状态。 然后,当您保存时,您可以决定发布它,然后所有其他用户将在其订阅中收到该文档。

希望替代解决方案能够帮助您

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM