我目前正在开发一个新的 Web 应用程序。
这是我第一次将 requirejs 与 AMD 模块一起使用。
据我了解,适应新的范例并不容易 -全局命名空间中没有变量。
在以前的 Web 应用程序中,我总是在全局命名空间中有一个变量,我可以使用它来跨不同模块共享多个资源。
现在,使用 requirejs AMD 模块,我使用backbone.js 和jquery(两个 amd 版本 - jquery 1.7.1 和backbone.js 0.5.3-optamd3)。
在我的应用程序中的某个位置,我从服务器(用户对象)获取backbone.js 模块。我想从不同的 AMD 模块访问该模块。我还想要一个应用程序范围的事件对象。
你能告诉我:在 requirejs AMD 中跨不同模块共享资源的正确方法是什么?
I'm currently developing a new web application.
This is the first time I'm using requirejs with AMD modules.
It's not that easy to get used to that new paradigm that there are - as I understand it - no variables in the global namespace.
In previous web applications I always had one variable in the global namespace which I could use to share several resources across different modules.
Now with requirejs AMD modules, I use backbone.js and jquery (both amd versions - jquery 1.7.1 and backbone.js 0.5.3-optamd3).
Somewhere in my application I fetch a backbone.js module from the server (user object). I would like to have access to this module from different AMD modules. I also want to have an application wide event object.
Could you tell me: what is the right way in requirejs AMD to share resources across different modules?
发布评论
评论(5)
我自己找到了解决方案。
谢谢 IntoTheVoid 的回答,但我希望有一个类似 AMD 的解决方案。这不再意味着“污染”全局命名空间。
我的解决方案有两个关键:
“https://github.com/addyosmani/backbone-aura”来自 Addy Osmani 和“https://github.com/amdjs/amdjs-api/wiki/AMD" 异步模块定义 (AMD) API 规范。
规范说:“如果工厂是一个函数,它应该只执行一次。”
因此,如果在 Web 应用程序中多次将 amd 模块指定为依赖项,则该依赖项不仅不会多次加载,而且不会多次执行,这对我来说是新事物。它只执行一次,并保留工厂函数的返回值。具有相同路径的每个依赖项都具有相同的对象。这改变了一切。
因此,您只需定义以下 amd 模块:
现在,在您想要共享资源的模块中,您将这个 app_registry 模块声明为依赖项,并在其中一个模块中写入:
并在另一个模块中写入:
I found a solution myself.
Thank you, IntoTheVoid, for your answer, but I was hoping for an AMD-like solution. This means, not again, "polluting" the global namespace.
There were 2 keys to my solution:
"https://github.com/addyosmani/backbone-aura" from Addy Osmani and "https://github.com/amdjs/amdjs-api/wiki/AMD" the The Asynchronous Module Definition (AMD) API specification.
The spec says: "If the factory is a function it should only be executed once."
So, if an amd module is specified multiple times as a dependency in an web application, the dependency is not only NOT LOADED MULTIPLE TIMES, it is also NOT EXECUTED MULTIPLE TIMES, and this is the new thing to me. It is only executed once and the return value of the factory function is kept. Each dependency with the same path has the same object. And this changes everything.
So, you simply define the following amd module:
Now, in those modules where you want to share resources, you declare this app_registry module as dependency and write in one:
and in the other:
要回答有关如何提供应用程序范围的事件对象的问题,您可以创建一个名为 globalContext 的 amd 模块并在 main.js 中实例化它。
此后,您可以将设置附加到 globalContext 并使用全局上下文来创建子组件等。
在 global-context.js 文件中,我们可以执行诸如加载子模块之类的任务,
这就是我们在 BoilerplateJS,大规模 javascript 产品开发的参考架构。
To answer your question as to how to provide an application wide event object, you can create an amd module called globalContext and instantiate it in the main.js.
Thereafter you can attach settings to the globalContext and use the global context to create subcomponents etc.
In the global-context.js file we can then perform tasks such as loading child modules
This is what we have implemented in BoilerplateJS, a reference architecture for large scale javascript product development.
您可以使用初始化模式将任何值注入 requirejs 模块(也称为“依赖注入”)。
在代码中的任何位置进行 require 调用:
将 module.js 文件定义为
You can use the initialize pattern to inject any value into a requirejs module (aka 'dependency injection').
Do a require call anywhere in your code:
With module.js file defined as
您可以在入口点 AMD 模块中定义单个全局
APP
。APP
可以创建并保存对其他共享模块的引用:You can define a single global
APP
in your entry point AMD module.APP
could create and hold a reference to other shared modules:只需对您自己的答案进行评论 - 您不需要在 app_registry 模块中定义函数:
应该足够了。
请参阅:文档
不过,请小心这些事情。在某些用例中,共享数据模块是有意义的。但是,如果您最终将其用作伪全局命名空间,那么它并不比仅使用全局变量好多少(并不是说这就是您正在做的事情)。
Just a comment on your own answer - you don't need to define a function in your app_registry module:
Should suffice.
See: the docs
Be careful with these things though. There are usecases where shared data modules make sense. But if you end up using it as a pseudo global namespace, it's not much better than just using globals (not saying that's what you're doing though).