cujojs / wire

A light, fast, flexible Javascript IOC container
Other
862 stars 71 forks source link

Using properties or methods of other modules or components as components #174

Open ghost opened 8 years ago

ghost commented 8 years ago

I've been using Wire for several node.js projects and it's been great. While designing wire specs I repeatedly found myself wanting to use the methods or components of another module or component as a component. I've read through all the documentation but couldn't seem to find a way to do this. For example:

define({
    doSomething: {
        module: "aComponent.someMethod"
    }
    // doSomething is someMethod of aComponent
});

You could do the same for create, which would instantiate the constructor or class using the same logic to instantiate modules:

define({
    anInstance: {
        create: "aComponent.SomeClass"
    }
    // anInstance is a new instance of SomeClass of aComponent
});

You could pass methods around as properties or arguments:

define({
    aComponent: {
        module: "aComponent",
        properties: {
            aMethod: {
                module: "anotherComponent.aMethod"
            }
        }
    }
    // aMethod of anotherComponent is injected to aComponent as aMethod
});

define({
    anInstance: {
        create: {
            module: "aComponent",
            args: [
                { module: "anotherComponent.someProperty" }
            ]
        }
    }
    // someProperty of anotherComponent is passed to aComponent to create anInstance
});

And if you can reference a top level method of a component, why not make it possible to reach deep down into a component too:

define({
    aComponent: {
        module: "anotherComponent.foo.bar.baz.someProperty"
    }
    // aComponent is someProperty, which is deeply nested inside anotherComponent
});

And references would be able to reach into a component declared elsewhere:

define({
    aComponent: {
        create: "aComponent"
    }

    anotherComponent: { $ref: "aComponent.someProperty" }
    // anotherComponent is someProperty of whatever aComponent is declared as
});

Right now the only way I see to achieve this is to extract each method or property into its own module. However, a lot of the time it makes more sense for a module to provide a collection of methods, but then it isn't possible in the current wire to use each of those methods as components.

It would be really cool this could be possible in Wire. Since it's already possible to compose component methods using dot syntax, I'm proposing that it should also be possible to use component methods as components, using the same syntax. I think its also somewhat similar to wire/dom in its ability to reach into a dom.

What do you think? Is there a really obvious way to do this that I'm missing? Should a plugin be created for this, or could this be something that belongs in the core?