简体   繁体   English

javascript获取已经渲染的Mongo字段的值-流星

[英]javascript get value of Mongo field already rendered - Meteor

Hey everyone, thank you very much for your help. 大家好,非常感谢您的帮助。 Question is edited per suggestions in the comments. 根据评论中的建议编辑问题。

I'm new to Mongo and Meteor. 我是Mongo和Meteor的新手。

I have a collection "posts" with a field "slug". 我有一个字段“ slug”的集合“ posts”。

The "post" template is populating correctly with each post's values. “帖子”模板正确填充了每个帖子的值。 Slug value is always something like "my-great-post". ug值始终类似于“ my-great-post”。

I need to get the text value for the _id's slug, which will be different each time the template is accessed, encode it, write a string, and spit the string back out into the template. 我需要获取_id的子句的文本值,每次访问模板时,文本值都会有所不同,对其进行编码,编写字符串,然后将字符串吐回到模板中。

Things tried 尝试过的事情

  • can't return a value for "this.slug" or "this.data.slug" in either template helpers or onRendered, even though collection is defined and correctly populating spacebars values in the template 即使定义了集合并在模板中正确填充了空格键值,也无法在模板助手或onRendered中返回“ this.slug”或“ this.data.slug”的值

  • "this" returns "[object Object]" to console.log “ this”向console.log返回“ [object Object]”

  • app crashes when I try to javascript encode and deliver a string from the helper, probably I don't fully understand helper syntax from the documentation 当我尝试对帮助程序进行javascript编码和传递字符串时,应用程序崩溃,可能是我无法从文档中完全了解帮助程序语法

(I followed advice in the comments to avoid trying to create scripts in the template html, so below is more information requested by everyone helping on this thread) (为了避免尝试在模板html中创建脚本,我遵循了注释中的建议,因此下面是每个对此线程提供帮助的人都要求的更多信息)

- Template html - -模板html-

{{#with post}}

<div class="blog-article">
  <div class="blog-header">
    <div class="left">

      <!-- title -->
      <h1 class="post-title">{{title}}</h1>

      <div class="holder">
        <div class="post-tags">
          <!-- tags -->
           {{#each tags}}
              <span>{{this}}</span>
           {{/each}}
        </div>
      </div>

    </div>

  </div> 

  <div class="blog-post">
    <div class="blog-copy">

      <!-- date -->
      <div class="post-date">{{post_date}}</div>

      <!-- social -->  
      <div class="blog-social">
         <!-- 
               <a class="so-facebook" target="_blank" href="need to encode slug here"></a>
         -->       
       </div>

       <!-- ============== post ============== -->

       {{{content}}}

       <!-- ============ end post ============ -->

     </div>
  </div>
</div>

{{/with}}

- Template js - -模板js-

Template.post.onCreated(function() {
  var self = this;
  self.autorun(function() {
    var postSlug = FlowRouter.getParam('postSlug');
    self.subscribe('singlePost', postSlug);  
  });
});

Template.post.helpers({

  post: function() {
    var postSlug = FlowRouter.getParam('postSlug');
    var post = Posts.findOne({slug: postSlug}) || {};
    return post;
  } 

   // can't get these working in a helper, out of helper they crash the app 
   // console.log(this.slug);   
   // console.log(this.data.slug);

});

Template.post.onRendered( function () {

   // these do not work 
   // console.log(this.slug);   
   // console.log(this.data.slug);

}); 

db.posts.findOne(); db.posts.findOne();

{
  "_id" : ObjectId("576c95708056bea3bc25a91f"),
  "title" : "How Meteor Raised the Bar For New Rapid-Development Technologies",
  "post_date" : "May 28, 2016",
  "image" : "meteor-raised-the-bar.png",
  "slug" : "how-meteor-raised-the-bar",
  "bitlink" : "ufw-29Z9h7s",
  "tags" : [
    "Tools",
    "Technologies"
           ],
  "excerpt" : "sizzling excerpt",
  "content" : "bunch of post content html"
}

If some one can solve this using any method, I will accept answer with joy and gratitude most intense. 如果有人可以使用任何方法解决此问题,我将以最强烈的喜悦和感激之情接受答案。

The problem is probably with the parent template, rather than this one. 问题可能出在父模板上,而不是这个模板上。 The way that Meteor works is that the JS files are separated from the HTML, so don't try to include a <script> tag in the HTML. 流星的工作方式是将JS文件与HTML分开,因此不要尝试在HTML中包含<script>标记。

The first thing is that you have to load all of your documents into the client. 第一件事是您必须将所有文档加载到客户端中。 (NOTE: once you've got the hang of that, then you can worry about only loading the documents that you need). (注意:一旦掌握了这些要点,就可以担心只加载所需的文档)。

To do that, you need a collection and a publication. 为此,您需要收藏和出版物。 By default all collections are automatically published completely, so unless you removed the autopublished module, then I'll assume that it is still loaded. 默认情况下,所有集合都会自动完全发布,因此,除非您删除了自动发布的模块,否则我将假定它仍处于加载状态。

So let's start with the parent template. 因此,让我们从父模板开始。 In this case, I'm going to just loop through all of the posts in the collection and display them using the innerTemplate. 在这种情况下,我将遍历集合中的所有帖子,并使用innerTemplate显示它们。

<template name=parent>
  <ul>
  {{#each post}}
    {{> innerTemplate}}
  {{/each}}
  </ul>
</template>

And now our inner template might look like this: 现在我们的内部模板可能如下所示:

<template name=innerTemplate>
  <li>{{slug}}</li>
</template>

The end result will be a simple list with each slug. 最终结果将是每个子弹的简单列表。

Now, to link everything together, we need to create a JS file, which will: 1. define the collection on both client and server 2. pass the collection to the parent template 现在,要将所有内容链接在一起,我们需要创建一个JS文件,该文件将:1.在客户端和服务器上定义集合2.将集合传递给父模板

This file should be accessible to both the client and the server. 客户端和服务器都可以访问该文件。

posts = new Mongo.Collection('posts');

if(Meteor.isClient) {
  Template.parent.helpers({
    posts() {
      return Posts.find();
    }
  });
}

Now, if you want to do something with 'slug' in the JS file, you could do something like this: 现在,如果您想对JS文件中的“ slug”进行操作,则可以执行以下操作:

if(Meteor.isClient) {
  Template.innerTemplate.helpers({
    upperCaseSlug() {
      return this.slug.toUpperCase();
    }
  });
}

Then, you could refer to upperCaseSlug in your template, like thus: 然后,您可以在模板中引用upperCaseSlug ,如下所示:

<template name=innerTemplate>
  <li>{{upperCaseSlug}}</li>
</template>

A few things about Meteor: 关于流星的几件事:

You should never see a pattern such as: 您永远都不会看到这样的模式:

<script type="text/javascript">
...some code
</script>

Because Meteor combines all your js files into one big file and includes it automatically in your app. 因为Meteor将您的所有 js文件合并为一个大文件,并自动将其包含在您的应用程序中。 You should never have to declare your own script in this way. 您永远不必以这种方式声明自己的脚本。

Secondly, you should never have to get the value of a data object by reading the DOM. 其次,您永远不必通过读取DOM来获取数据对象的值。 The data context of each template gives you your data in the variable this . 每个模板的数据上下文在变量this为您提供数据。

In either a helper or template event you can refer to this and be assured that you're going to get exactly the data being displayed in that instance of the template. 在辅助事件或模板事件中,您都可以参考this并确保可以准确获取在该模板实例中显示的数据。

Having now seen your template code it's now apparent that your template has no data context - you set the data context inside your {{#with post}} and its associated helper but that doesn't end up creating the this you need one level below. 现在,您已经看到了模板代码,很明显,您的模板没有数据上下文-您在{{#with post}}及其关联的帮助器中设置了数据上下文,但最终并没有创建this上下文, this您需要在以下一级。

So... @Nathan was on the right track except that he assumed you were iterating over a cursor instead of just looking at a single post. 所以... @Nathan处在正确的轨道上,只是他认为您正在遍历光标而不是仅仅看一个帖子。

Take all html you have between your {{#with post}} and {{/with}} and put it in a new template, say postDetail then make your outer template: 取出{{#with post}}{{/with}}之间的所有html并将其放入新模板中,说出postDetail然后制作外部模板:

<template name="post">
{{#with post}}
  {{> postDetail}}
{{/with}}
</template>

Now your postDetail template will get a data context equal to the post object automatically and your helpers can refer to this safely. 现在,您的postDetail模板将自动获得一个与post对象相等的数据上下文,并且您的助手可以安全地引用this

Template.postDetail.helper({
  slugURI{
    return "/"+encodeURI(this.slug);
  }
});

Then in your postDetail template you can get the encoded slug with: 然后,在您的postDetail模板中,您可以使用以下代码获取编码的代码块:

<a class="so-facebook" target="_blank" href={{slugURI}}>

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

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