Properties injections in module factory

75 views
Skip to first unread message

Denis Savenok

unread,
Apr 7, 2014, 3:40:21 PM4/7/14
to
Can I insert properties as if they were injected, if I use module factory?
For example, in Backbone.Marionette framework: (.coffee)

    switchItemView:
        module: "controls/switch/item/switchItemView"
        # it would be nice to inject some properties for switchItemView here, instead of passing them through {$ref: 'switcher}-instance

    switcher:
        create: 
            module: "controls/switch/switchControl"
            args:
                name: "switcher"
        properties:
            # itemView must be a class for all subviews
            itemView: {$ref: 'switchItemView'}

Or module factory only loads a module without calling, and therefore it does not passed through lifecircle phases - and no choice to inject anything?

UPD: and is it right if no lifecircle phases processing, no help from custom plugin can be obtained?

Denis Savenok

unread,
Apr 8, 2014, 12:41:18 PM4/8/14
to cuj...@googlegroups.com
Plugin for prototype fields injection: https://gist.github.com/designeng/10068503
Sorry, without tests yet.

Brian Cavalier

unread,
Apr 8, 2014, 2:38:31 PM4/8/14
to cuj...@googlegroups.com
Hey Denis,

You're right in that there's no special plugin feature that allows you to configure a constructor's prototype directly.  Aside from creating a new plugin (I saw your gist, but haven't looked at it closely yet), another option may be to use `create` to create an instance, which you can use as a prototype for creating other instances.


I've used that in several situations, and it has worked out well.  It's very much like using Object.create.

Rather than using wire to do it, another option might be simply to create a module that begets a new constructor+proto from the original using Object.create and configures it.  Then you could `create` instances of that new constructor using wire.  That spreads your configuration out a bit more, so it may not be ideal, but again, may be fine depending on the situation.

If you do go the route of setting properties on an existing prototype directly, just remember that you'll be modifying the prototype for all code in the same VM that uses that prototype.  Personally, I'd probably look for another way, but as long as that's ok for your situation, creating a plugin to do it would probably work out well.

Cheers,
b

eschwartz

unread,
Apr 9, 2014, 10:24:31 AM4/9/14
to
Denis -- I created a WireJS plugin to do just that. I had the same issue, that I wanted to configure a view's behavior, than pass the view's constructor on to another object. Otherwise, you end up having to create modules for each ItemView, which are nothing but configured subclasses. Why not keep all the configuration in one place?

I ended up with a ClassFactory plugin that works like this:

{
  MyItemView: {
    ClassFactory: {
      module: 'myApp/views/baseItemView',
      args: [{
        className: 'some-class',
        template: { module: 'hbs!myApp/templates/myTemplate' }
        ui: {
          btn: 'button.someButton'
        },
        // etc...
      }]
    }
  },

  myCollectionView: {
    create: {
      module: 'myApp/views/baseCollectionView',
      args: [{
        collection: { $ref: 'myCollection' },
        view: { $ref: 'MyItemView' }
      }]
    }
  }
}

What the ClassFactory plugin does is create a sub-class of the base module (excuse my OOP-speak, please), which is bound to the provided options argument. 

As my arguments are usually options objects, the ClassFactory will extend any arguments provided on instantiation with the default bound arguments. So when Marionette.CollectionView creates the ItemView instance, the view is created with all the configured options:

view = MyItemView({
   model
: someModel
});
view
.model === someModel;                   // true
view
.options.className === 'some-class';    // true



The plugin is currently embedded in another open-source library I'm working on. I never pulled it out because I was worried it was too specific to what I was doing. But if you're interested, we could maybe work together to pull it out into it's own repo.

Here are the relevant modules:
I have a few other Backbone/Marionette plugins for WireJS, as well, if you're interested:
Next on my list is to create a set of plugins for handling Marionette component lifecycle events... if this is something people would use, maybe I should start up a Mariontte-WireJS plugins repo.

Edan

------

FYI - here are the tests:

Denis Savenok

unread,
Apr 13, 2014, 6:35:33 AM4/13/14
to
Brian, thank you for the gist, the way you offer is very intresting, I will try it. 
I suggested the extending plugin just as tribute for wire's DSL conciseness.

Edan, thank you too, listenTo and others are great. I discovered aerisjs a week ago looking for wire-backbone.marionette integration and now study it carefully. Have you any discussion area for it?
You are right, the Marionette-WireJS repo seems to be very usefull, and I would be happy to participate in the creation any parts of it.

Denis

eschwartz

unread,
Apr 21, 2014, 10:33:56 AM4/21/14
to cuj...@googlegroups.com
I was chatting with some folks from Marionette, and they were very interested in learning more about WireJS/Marionette integration.

I'll see what I can do about about publishing my Marionette plugins -- it's going in my backlog :)

Brian Cavalier

unread,
Apr 22, 2014, 9:46:07 AM4/22/14
to cuj...@googlegroups.com
Sounds great, eschwartz!  Please do keep us posted :)
Reply all
Reply to author
Forward
0 new messages