【问题标题】:Meteor template rendered twice流星模板渲染了两次
【发布时间】:2017-03-16 19:10:20
【问题描述】:

这个 Meteor 客户端Template.payment.onRendered 被触发了两次,它调用了服务器端方法两次,如果它必须执行两次渲染,我怎样才能让它触发一次后端方法,否则它怎么能让它只渲染一次?谢谢

//client
Template.mainMenu.events({
  'click .menuItem': (event) => {
    let menuShortName = event.currentTarget.dataset.template;
    Session.set('taskSelected', menuShortName);
    Meteor.call('mainAction', menuShortName);
  }
});

Template.index.helpers({
  'taskInputs': function () {
    let task = Session.get('taskSelected');
    let tasks = task ? task.split(',') : [];
    let data = DisplayCol.find({action: {$in: tasks}}, {sort: {createdAt: 1}}).fetch();
    return {items: data};
  }
});

//server
  'mainAction': function (menuShortName) {
    DisplayCol.remove({userId: this.userId});
    lib.displayMakeUp({'action': menuShortName});
  },

      'displayMakeUp': (doc) => {
      for (let i = 0; i < attrItems.length; i++) {
        if (attrItems[i].action === doc.action || attrItems[i].action.indexOf(doc.action + '_') >= 0) {
          let group = {};
          group = attrItems[i];
          group.userId = Meteor.userId();
          console.log(JSON.stringify(group));
          DisplayCol.insert(group);
        }
      }
    },


 Template.payment.onRendered(function () {
   Meteor.call('getClientToken', function (error, clientToken) {
     if (error) {
       console.log(error);
     } else {
       braintree.setup(clientToken, "dropin", {
         container: "payment-form", // Injecting into <div id="payment-form"></div>
         onPaymentMethodReceived: function (response) {
           var nonce = response.nonce;
          console.log(nonce);
      }
    });
 }
});
});

模板:

<body>
  {{> header}}
  {{#if currentUser}}
    {{#if isVerified}}
      {{> index}}  <-------------------------- (1) 
    {{else}}
      <br><br><br><br>
      <p>Check your email for your verification link!</p>
    {{/if}}
  {{else}}
    {{> terms}}
  {{/if}}
</body>

<template name="index">
  <div id="main">
    {{#if (display 'mainMenu')}}
      {{> mainMenu}}
    {{else}} {{#if (display 'content')}}
      {{> Template.dynamic template="content" data=taskInputs}}  <------------------- (2)
      {{#if (session 'showFooter')}}
        {{> footer}}
      {{/if}}
    {{/if}}{{/if}}
  </div>
</template>

<template name="content">
  {{> subMenu}}
  <div id="main">
    <div id="content">
      <form>
        <button type="submit" style="display:none"></button>
        {{#if Template.subscriptionsReady}}
          {{#each this.items}}
            {{> sub}}  <---------------------------------- (3)
          {{/each}}
        {{/if}}
      </form>
    </div>
  </div>
</template>

<template name="sub">
 {{#if isEqual element "payment"}}
    {{> payment}}  <--------------------------------------- (4)
  {{/if}}
</template>

<template name="payment">
  <form role="form">
    <div class="row">
      <div class="col-md-6 col-xs-12">
        <br>
        <div id="payment-form"></div>
        <button type="submit" class="btn btn-success">Submit</button>
      </div>
    </div>
  </form>
</template>

【问题讨论】:

  • 您的"getClientToken" 方法是仅服务器还是客户端和服务器两者?
  • 服务端定义,客户端调用

标签: meteor


【解决方案1】:

根据我所看到的,您似乎正在将模板呈现在 each 块内。这将为每个 each 迭代呈现一个模板实例。

{{#each this.items}}
  {{> sub}} <---------------------------------- (3) 
{{/each}}

请记住,每个模板实例都会触发其所有回调(包括onRendered)。如果您只想要一个实例,请将其从each中取出

【讨论】:

  • 但是在提供数据的集合中,payment 模板只有一个文档。我检查了它在添加文档时只循环一次。每个文档都是一个 html 元素,因此我可以通过修改提供的文档轻松地将元素添加到 html。我会尝试发布代码。
  • 嗯...所以您在加载页面时只会呈现 1 个提交按钮?
  • 是的。只有一个提交按钮。请参阅我将很快发布的图片,其中显示了 2 个付款表单,而不是预期的只有一个,而是一个按钮。
  • 听起来不傻,但是您是否有机会从创建 2 个贝宝表单的任何模板的 onRendered 回调写入控制台,这就是您所看到的?
  • 我粘贴了 Template.payment.onRendered 的实际代码
【解决方案2】:

尝试使用this package 来限制渲染。你也可以 yield sub to payment(而不是检查元素)尝试检查这是否是你的路线中的第一次运行。

  //html
  {{> yield sub}}

  //router
  if (Tracker.currentComputation.firstRun) {
    this.render("payment",{to:"sub"});
  }

【讨论】:

  • 这是一个单页应用,不使用路由器。所以{{&gt; yield sub}} 而不是{{&gt; sub}} 给出了许多浏览器错误并且页面没有加载。我添加了 konecty:nrr 包并将{{&gt; sub}} 替换为{{#nrr nrrargs 'sub' element=element}}{{/nrr}},如果我做得正确,一些模板根本不会被渲染,特别是有问题的支付模板。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
  • 2016-01-26
  • 2013-11-16
  • 1970-01-01
相关资源
最近更新 更多