-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Extend modules #837
Comments
Edit: Some discussion below on me failing to understand the requirements of the request, jump to this comment for a TLDR version :). What functionality are you looking to add in a custom module class? |
Since my initial post, I've discovered the same issue applies to Regions so I've edited the issue accordingly. To answer your question, I'm building a collection of reusable components to use across different applications. These components are groups of views and a module that can be inserted into a page to add some functionality. For instance, there might be a pie graph component that I want to abstract from a given app. You add it as a module to your app to include it. To make it work, all you need to do is pass it a model to get the data from and the region to put it in, and it does the rest for you (like magic!) To accomplish my goal I need to extend the functionality of every Marionette class in each components (the item views, the controllers, and so on). One thing I want to add to everything is a local I got around the issue of attaching the An example of why this is important is the following: consider that my pie graph is added to the DOM at some time, but takes a second to fully animate its introductory animation. I would like to internally share both of these events with my component using the Maybe there's some way to get around this that I'm not seeing. If you have any ideas I'd love to hear them. |
You can specify custom region class when declaring them on the app, take a looks at the docs. Hopefully that sorts you out for Regions. As for modules, I'm still not entirely understanding what sort of custom functionality you might attach to a module. Do you think you could provide a brief concrete example on how you'd leverage custom Module classes? Sometimes times code is worth a thousand words :) |
Ah, look at that. I should have taken another look at the docs before updating regarding regions. In regards to modules, it seems that switching things over to a controller has solved my issues with needing a custom module type for now. I'll go ahead and mark this issue as closed. Thanks, cobbweb! |
Awesome, glad I could help. :) Yea I had a feeling you might have been stretching the purpose of Marionette.Module a little far. They're more like code organisation modules rather than UI/widget type modules. That's an interesting concept though so thanks for bringing it up. |
I'm reopening this because as I'm writing more code I think the issue may still be unsolved, actually. I am trying to use modules as a UI/widget module with this structure, and I think this makes more sense than using any other type of Marionette object. Modules can be plugged in, started, and stopped directly from the application. This is ideal for UI/widgets! It's hard for me to think of any other Marionette class that fits the bill for how I'd want a UI/widget module to behave. To show some code, most modules I make will need the following code in an initializer:
where Components.Controller is a special controller for these types of modules. But on some modules, I might not want this at all. Or maybe I'll want to use a different controller. Or maybe I'll pass more options in. In any event, I need a way to overwrite this initializer. The best way to do this, of course, is to extend the base It seems like adding a way to attach modules like regions are attached would improve the utility of Modules and allow them to be used as a UI/widget class. But perhaps it'd be better to just use a |
Yes you're right, I take my words back. You're aware that you can add Module Initializers right? |
Yeah, I'm familiar with that feature. And I might be wrong here, but I don't think it can be used for extending classes that's as 'behind the scenes' as extending, say, an ItemView. Let's say I have some base module, say, |
A bit sleep deprived at the moment, thanks for bearing with me. Could you disable If you wanted something generic to occur with each module, you could move that code to a shared function which you might attached to your app. Then just add that as an initializer, if you wanted to override it, simple don't at it as an initializer for that module and register a custom one. If that's the case, in does feel like we're working around limitations with the module class and I'm starting to warm up to your idea of allowing custom modules. |
Yeah, sorry, it's probably partially my fault at not clearly expressing my thoughts here. But you're definitely on the right track with the generic code occurring at the start of each module. However, I want to go even further than that. I want it to have two important properties: I want it to be automatic (the user shouldn't need to manually add the initializer), and I want it to be overwrite-able. These are the exact same properties that Backbone's extend method gives us, which is why the default Backbone objects (and many of the default Marionette ones) are so useful. To explain the extend bit more, what I'm aiming for is very similar to the relationship between Views and ItemViews in Marionette. There's a base thing, a I'm thinking that if modules were this same way, then Marionette would be in a good place for a UI/widget framework to be built on it. One important thing to note is that I don't think the Does this help explain it better? Sorry if I'm being unclear, or just repeating myself over and over. |
Yep starting to make sense now, I'll think this over today :) |
TLDR: Need a way to add generic start up functionality to every module by default, which could be overridden/disabled on a per module basis. The request seems viable, and I can't see a way to do this without monkey-patching the core... what do you think @samccone? Two ways I can see this happening:
|
Use case: Building reusable "modules" that can be plugged in to, and removed from, applications at will. These modules are self-contained groups of classes that have an API to interact with them, but otherwise they require minimal set up to add to your app. They might involve a view, in which case you'd pass it a I want to use modules because of their nice properties of plugging them into and out of applications. And I want to assume a default structure to my modules in a way very much like how Marionette assumes a default structure to its I'm beginning to create this idea over at this incredibly nascent repository, Puppets. Here's an example 'base module', which is using controllers now with a shim to imitate the plug-and-play ability of Marionette modules. Here's an example Puppet that adds a bit of functionality to the base one – not too much, but enough to get the idea, I think. |
cool @jmeas I get what you are going for. Can you make like a super simple example just so we have an idea of scope of what it can touch / interact with along with a mock interface API? |
Sure. Clone this repository and run By default, the puppets are closed. You can open them up by executing the command The command So Of course, by extending this base puppet class you can see how it's be easy to add more API commands and requests. |
If you'd like, I could make a PR implementing the first suggestion in this comment for review. That suggestion seems more powerful than the other suggestion, seems easier to implement, and would allow for a more consistent development process for extended modules. The consistency would come from giving modules the same Backbone.extend functionality that the other components have. |
that would be a great start @jmeas |
I'm a bit late to the game here, but this thread caught my eye because I've had to work around this exact issue. The technique I used to extend base functionality in Marionette modules was to supply a
Because multiple calls to Application.Module() end up mimicking the
This all has worked great for us, but I think the |
👍 Interestingly from the 1.0 post: http://lostechies.com/derickbailey/2013/03/25/marionettejs-v1-0-now-with-stickers/
|
I'm glad that this issue has progressed into a nearly-ready PR, but I still think share the same concerns about Modules that Derick points out in that post (nice link, by the way!). It seems weird to me that some people will be using them to namespace their code, while I'll be building a UI/widget/component library with them. I think these thoughts are what led me to make this recent issue of mine, but I'm still undecided on whether I actually think modules are doing too much or not. Would it make more sense to separate them out as potentially three things: namespace objects, sub-apps, and components? Any thoughts anyone? |
Yes something isn't right with modules. You can see why I came up with my falsy statement earlier about them being for code management. Trying to split code management/dependency injection away from sub-apps is definitely something that needs to happen; though I'm not sure what the way forward is :/ Thanks for your commitment to this PR/issue @jmeas, really appreciate your efforts :) |
v2 we can flag modules for a rewrite, since they are pretty crazy right now |
Funnily enough, it's come to my attention this afternoon that I actually need this functionality myself. I've got a rip-off of I wanted to make every module have a |
As it stands it is very difficult to extend Modules to create a new base type in your app. This makes Modules unique, in that all of the other components of Marionette (and Backbone) are easily expanded upon. For instance, if I wanted to make a new 'base' type of ItemView, I could easily accomplish this with by Backbone extending the class to make a new one, then just instantiate that new one whenever I wished.
This isn't possible with Modules for a number of reasons.
Application.module
, which forces you to useMarionette.Module.create...
(Line 86). This prevents you from defining a new 'base' module from which to extend from.I didn't make a PR on this issue just yet because I want to make sure whichever solution I code up is acceptable to the maintainers of Marionette.
The best option, I think, would be to allow users to override that line 86 of Application programmatically. This allows the initialization of modules to remain the same so that backwards compatibility isn't lost. One way to do this would be to pass an optional third argument to the
Application.module
method which is the class to instantiate on line 86. If it's missing it defaults to the current class.Thoughts?
The text was updated successfully, but these errors were encountered: