草庐IT

javascript - 了解 Meteor 何时重新计算我的模板助手

coder 2023-11-01 原文

我正在努力思考 Meteor 的 react 性。我知道当模板中引用的 react 性数据源发生变化时,它会重新呈现页面。我还了解什么是 react 源(Session、MongoDB 游标等)。

我无法理解的是所有这些对我的模板助手的“背后”调用。似乎除了 react 性之外还有其他因素导致了它们。

特别是,在下面的代码中,我有一个 friendRequests 助手,它在 期间有时被重新计算 两次 有时 三次单次 访问/friends 页面。如果重新计算两次,则数据库查询成功!如果它被重新计算三次,第一次数据库访问(出于某种奇怪的原因)无法查询数据库,而后两次成功。

这是数据库失败时的堆栈跟踪:

// NOTE: imsolonely is one of the users that should be returned in the friendRequests
imsolonely's public key: undefined
debug.js:41 Exception in template helper: TypeError: Cannot read property 'profile' of undefined
    at Object.Utils.getPublicKeyByUsername (http://localhost:3000/lib/utils.js?acf4e03d4c8a70819c26f8d2fd08caf7100768fe:79:22)
    at Object.Utils.getFingerprintByUsername (http://localhost:3000/lib/utils.js?acf4e03d4c8a70819c26f8d2fd08caf7100768fe:88:24)
    at http://localhost:3000/client/friends.js?dbec4a7537c9d0abf56a74489824969cb7baadfe:25:35
    at Array.forEach (native)
    at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
    at Object.Template.friendRequests.helpers.friendRequests (http://localhost:3000/client/friends.js?dbec4a7537c9d0abf56a74489824969cb7baadfe:22:7)
    at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:2693:16
    at http://localhost:3000/packages/blaze.js?77c0809654ee3a10dcd5a4f961fb1437e7957d33:1602:16
    at Object.Spacebars.dot (http://localhost:3000/packages/spacebars.js?3c496d2950151d744a8574297b46d2763a123bdf:231:13)
    at http://localhost:3000/client/template.friends.js?a2da726f6dad1aaecfdedfe216aa3378fff938b5:24:37
utils.js?acf4e03d4c8a70819c26f8d2fd08caf7100768fe:78 imsolonely's public key: {"profile":{"publicKey":"0404b4880129edc1ea2652dd1eff1c8728269874b9b0ace02cc90edcb449c3f3d716c2f8b79a5fe5695d52cd85aed228f977073538625e8e71f1cfd764766669b1"},"_id":"sXjzt7YHA8KTyAib5"}
utils.js?acf4e03d4c8a70819c26f8d2fd08caf7100768fe:78 imsolonely's public key: {"profile":{"publicKey":"0404b4880129edc1ea2652dd1eff1c8728269874b9b0ace02cc90edcb449c3f3d716c2f8b79a5fe5695d52cd85aed228f977073538625e8e71f1cfd764766669b1"},"_id":"sXjzt7YHA8KTyAib5"}

这也发生在我的许多(或全部,不确定)助手身上。它们在甚至不需要时被调用,因为用户未登录(并且未呈现模板,因此不应重新计算帮助程序)。

这是一些代码:

client/friends.js:

Template.friendRequests.helpers({
  friendRequests: function () {
    // Problem 1: The template gets called right after I log in but before I am fully logged in
    // so I need this call here.
    if(!Meteor.user())
      return Utils.notLoggedInErrorMsg;

    // Problem 2: The template gets called three times. The first time fails the DB query
    // as if the DB row did not exist. The next 2 times it succeeds. But it should only be
    // called once.
    var reqs = Friends.getFriendRequests(Utils.me());

    _.each(reqs, function(element, it, list) {
      check(element.initiator, String);
      // Get the user's fingerprint
      element.fingerprint = Utils.getFingerprintByUsername(element.initiator); 
    });

    return reqs;
  },  
});

client/friends.html:

<template name="friends">
  {{> friendRequests}}
  {{> searchForm}}

  <h2>My friends</h2>
  <ul>
  {{#each friends}}
    <li>{{this}}</li>
  {{/each}}
  </ul>
</template>

<template name="friendRequests">
  <h2>Friend requests</h2>
  {{#if friendRequests.length}}
    <p>Someone's popular today!</p>
    <ul>
    {{#each friendRequests}}
      <li><b>{{initiator}}</b> with fingerprint <pre style="display: inline">{{fingerprint}}</pre> sent   you a request on <em>{{date}}</em>. <a href="#">Accept <b>{{initiator}}</b> as a friend?</a></li>
    {{/each}}
    </ul>
  {{else}}
    <p>Sorry, nobody likes you right now.</p>
  {{/if}}
</template>

lib/utils.js:

Utils = {
  // ...
  // other stuff
  // ...

  // @return a hex-encoded public key as a string
  getPublicKeyByUsername: function (username) {
    var user = Meteor.users.findOne({ username: username }, { fields: { 'profile.publicKey': 1 } }); 
    console.log(username + '\'s public key: ' + EJSON.stringify(user));
    var pubKey = user.profile.publicKey;

    return pubKey;
  },  

  // NOTE: not used yet, i used the CryptoUtils function directly when I needed it
  //  
  // @return the fingerprint as a hex-encoded string
  getFingerprintByUsername: function (username) {
    var pubKey = Utils.getPublicKeyByUsername(username);

    var fingerprint = CryptoUtils.getPublicKeyFingerprint(pubKey);

    return fingerprint;
  },  

  notLoggedInErrorMsg: 'Meteor is being silly and calling this when I\'m not logged in.',
}

如果重要的话,我正在使用 iron:router 1.0.3 包重定向到 /friends URL。

关于为什么 friendRequests 助手在不可见时被重新计算的任何澄清,为什么它有时被重新计算两次,有时三次,而不是当我刷新 /friends<> 页面将不胜感激!

谢谢, 阿林

最佳答案

一般来说,您应该预料到您的助手会被多次调用。如果您的模板在用户登录时呈现,并且没有等待数据发布,您的助手可能会运行:

  1. 请求路由时
  2. 当用户完成登录时
  3. Friends 数据首次到达客户端时
  4. 当其他 Friends 数据到达或被修改时

要解决第一个问题,您可以检查 Meteor.user() || Meteor.loggingIn() 就像我在对 this question 的回答中所做的那样(请注意,自从我回答该问题以来,路由器 API 已发生变化,但它应该让您了解该怎么做)。

第二个问题的答案可以在我在 guards 上的帖子中找到.简而言之,您不能假设数据已经到达客户端,因此您要么需要检查它是否存在,要么需要显式地 wait on在呈现模板之前在路由器中订阅。

关于javascript - 了解 Meteor 何时重新计算我的模板助手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27255235/

有关javascript - 了解 Meteor 何时重新计算我的模板助手的更多相关文章

  1. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  2. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  3. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  4. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  5. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  6. ruby - 我可以将我的 README.textile 以正确的格式放入我的 RDoc 中吗? - 2

    我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:

  7. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  8. jquery - 我的 jquery AJAX POST 请求无需发送 Authenticity Token (Rails) - 2

    rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

随机推荐