Skip to content

Instantly share code, notes, and snippets.

@trodrigues
Created February 9, 2012 17:48
Show Gist options
  • Select an option

  • Save trodrigues/1781533 to your computer and use it in GitHub Desktop.

Select an option

Save trodrigues/1781533 to your computer and use it in GitHub Desktop.
references inside references
// should this.modules.module1 work?
define({
appStructure: {
literal: {
module1: { $ref: 'module1' },
module2: { $ref: 'module2' }
}
},
module1: {
create: {
module: 'module1'
},
properties: { modules: {$ref: 'appStructure'} }
},
module2: {
create: {
module: 'module2'
},
properties: { modules: {$ref: 'appStructure'} }
}
});
@briancavalier
Copy link

A quick note on requiring a spec more than once. There is a small "gotcha" there when using wire as an AMD plugin, due to the way AMD loaders will cache the module definition, even when dealing with plugins. For example, if you do the following multiple times, it will only actually invoke wire the first time. Subsequent times, the loader will simply return the same wire context that was created the first time:

curl(['wire!my/wire/spec'], function(context) {
   // The first time, wire will be invoked and will create a new context from
   // my/wire/spec.
   // After that, wire will not be invoked, and the cached context will be returned
});

To wire the same spec multiple times, you can use wire as a module instead of a plugin. You can programmatically wire the spec as many times as you need, and each time, a new context will be created:

curl(['wire', 'my/wire/spec'], function(wire, spec) {
    // This will always invoke wire and create a new context.
    wire(spec).then(function(context) { ... });
});

Or, you can simply pass a module id to wire directly:

curl(['wire'], function(wire) {
    // This will always invoke wire and create a new context.
    wire('my/wire/spec').then(function(context) { ... });
});

However, the preferred way to get a handle on the wire function is by injecting it into any component using the wire! reference resolver. Here's a quick example:

define({
  module1: {
    create: {
      module: 'module1'
    },
    properties: {
        // Set the _wireMoreStuff to a function that will wire any spec passed to it
        // So, module1 can call this._wireMoreStuff('another/wire/spec') to wire more stuff
        // More info below
        _wireMoreStuff: { $ref: 'wire!' }
    }
  }
// ...
});

When using wire that way, it is actually a contextual version of wire, that will wire a child context of the current context. Creating hierarchies of contexts like this can be very useful, because child contexts can see components in their parent context, and thus can $ref them. You can read more about contexts and context hierarchies here. They are a very powerful part of wire, and we've come to use the hierarchy a lot when building complex systems.

You may also want to have a look at the wire factory, which is yet another way to "use" wire from within other components. The defer option can be especially powerful.

I'll second John's request for a private gist, if that's doable, when you get to a point where you can share. We'd certainly love to see how you're using cujo :)

@trodrigues
Copy link
Author

Oh, I see. The wire! reference resolver injected into the module is something I hadn't noticed before (maybe it could be better highlighted in the docs?) and it actually makes a lot more sense than always having to require the spec. And, having the spec cached is something I don't mind, and I actually expected it to work like that.

I was actually looking at contexts right now, as I have a possible use case for them. This app was organized under a global namespace with sub namespaces under it, and there's wasn't much thought of having a very organized interaction between modules, so there's things like submodules setting values on higher level namespaces. At times I struggle a bit figuring out the best way to do some things with this new workflow.

I'll try to show you guys some stuff when I get it working properly, but it still won't be pretty. Basically, turning the existing modules into AMD modules and using wire.js where it makes sense is the first step to the restructuring of this app. There's a lot of logic in views and other issues that will require some reorganization and splitting up of things and I thought it would be better to first get these tools in place before starting to do that sort of work.

Also, there's a few quirks regarding the way the app is bootstrapped and deployed (this is a Spotify App by the way!) that make it a bit different than most browser based single page apps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment