【问题标题】:Meteor.js/Handlebars.js - Understanding procedural coding styles & scopingMeteor.js/Handlebars.js - 了解程序编码风格和范围
【发布时间】:2014-01-08 20:14:30
【问题描述】:

我是第一次使用 Meteor.js 框架,我无法理解模板系统的事件顺序(从未使用过 Handlebars.js),以及如何处理范围。

我有一个名为audio.js 的文件。在其中,我定义了一个类并使用该类初始化一个变量:

// Question about this as well, how do I properly make a jQuery class?
// Is this the right way?
$.Audio = function() {}

$.Audio.prototype = {
  init: function() {
      this.ele = $('.blahblah');
  }
  startAudio: function() {
      // do things
  }
}

var Music = new $.Audio();

所以我的 var Music 是在 audio.js 内部创建的。

现在,在另一个 js 文件中,我正在做一些模板函数:

Template.bars.rendered = function {
    Music.startAudio();
}

但我从那行得到一个Uncaught ReferenceError: Music is not defined

主要问题:

作用域在 Meteor.js 中是如何工作的?如何引用我在另一个文件中的模板函数内的一个文件中声明的 Music 变量?

不太重要的问题,可能不容易回答,因为这不是一个很好的问题。如何在程序上用流星编写 javascript?这是我第一次使用模板。我习惯于在 DOM 中列出的 javascript 被渲染(或者当 DOM 被加载或使用监听器触发事件​​等)。我不明白如何使用模板将 javascript 中的逻辑事件链联系在一起。

【问题讨论】:

  • 完整阅读docs.meteor.com。 sry,但是解释概念,根据概念解决您的问题以及整个问题需要2个多小时。我个人认为你应该先开始尝试流星,然后研究文档和eventedmind.com 以适应流星。如果您发现了它,您可能想尝试编写自己的插件、扩展或库。 - 没有冒犯!

标签: javascript jquery node.js meteor handlebars.js


【解决方案1】:

来自 Meteor 文档:

  • 首先加载名为lib 的目录中的文件。

  • main.* 匹配的文件将在其他所有内容之后加载。

  • 子目录中的文件在父目录中的文件之前加载,因此最深的子目录中的文件首先加载(lib之后),根目录中的文件最后加载(main.*除外)。

  • 在目录中,文件按文件名的字母顺序加载。

另外,这里有一些关于导出变量的文档:

// File Scope. This variable will be visible only inside this
// one file. Other files in this app or package won't see it.
var alicePerson = {name: "alice"};

// Package Scope. This variable is visible to every file inside
// of this package or app. The difference is that 'var' is
// omitted.
bobPerson = {name: "bob"};

因此,如果您希望您的 music 变量在其他文件中可用,请执行以下操作:

  • 将您的 audio.js 文件放在 lib 文件夹中,例如 lib/audio.jsclient/lib/audio.js。这将确保它在其他文件之前加载。

  • 不要使用var 关键字声明您的music 变量。只需执行music = new $.Audio(); 这会将music 附加到全局范围,允许稍后加载的文件访问它。

为什么有必要这样做? Meteor 将您的所有文件包装在 IIFE 中。因此,例如,如果您的文件如下所示:

var MyClass = function() {};
var myInstance = new MyClass();

然后 Meteor 将像这样包装该文件:

(function() {
  var MyClass = function() {};
  var myInstance = new MyClass();
})();

由于 JavaScript 的函数作用域,现在 vars 不可用于其他文件。没有var 声明的变量被附加到全局范围,无论它们可能包含在什么函数中。

不太重要的问题,可能不容易回答,因为它不是一个很好的问题。如何在程序上用流星编写 javascript?这是我第一次使用模板。我习惯于在 DOM 中列出的 javascript 被渲染(或者当 DOM 被加载或使用监听器触发事件​​等)。我不明白如何使用模板将 javascript 中的逻辑事件链联系在一起。

去阅读文档。您可以通过http://docs.meteor.com/ 访问它们。阅读每一行 - 它会回答您可能遇到的许多此类问题。简而言之,你可以在模板上定义事件处理函数,当模板内的HTML元素发生事件时触发。您还可以在模板上定义辅助函数,它可以依赖于响应式数据源,并且当这些响应式数据源发生变化时会自动重新运行(这将导致模板重新渲染)。 Meteor 文档的模板部分对此进行了介绍。

想法是这样的:您的模板定义了应该为您的应用程序呈现的 HTML 的结构。此 HTML 由响应式数据源驱动,并且每次响应式数据源更改时都会重新呈现。这可确保您的 HTML 始终与您的数据同步,而您无需编写任何自定义 DOM 操作代码!所以,举个简单的执行顺序例子:

  1. 使用初始值创建反应式数据源(例如,SessionMeteor.Collection 或您自己的反应式数据源使用Deps)。

  2. 依赖于您的数据源的模板帮助函数使用数据源的初始值执行。

  3. 模板是使用辅助函数的结果呈现的,它包含在模板中,如{{myHelper}}。模板事件处理程序会自动附加到生成的 HTML DOM。

  4. 在 DOM 上触发事件,例如点击按钮。

  5. 事件处理程序正在运行。也许该事件处理程序会更改响应式数据源。

  6. 辅助函数看到数据源发生了变化,自动重新运行。

  7. 模板的相关部分会使用辅助函数中的新值自动重新渲染。

【讨论】:

  • 超级有帮助,感谢您的所有解释。我现在就通读文档。
猜你喜欢
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 2021-02-03
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多