-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
I have a need for what I typically think of as a mixin. In this case, it's a simple "loading..." message with a spinner gif. typical stuff, nothing special. but i want a re-usable component for this - one that i can display within any other view that needs it, when it needs it.
I thought, "behaviors!" - but it doesn't work the way I hoped.
If I define a method on my behavior, I have no way of invoking that behavior directly from within my view.
window.Behaviors.ShowLoader = Marionette.Behaviors.extend({
showLoader: function(){
// do stuff to show it, here
}
});
Marionette.ItemView.extend({
behaviors: {
ShowLoader: {
message: "loading ..."
}
},
events: {
"click .whatever": "clickedIt"
},
clickedIt: function(){
this.showLoader(); //=> undefined is not a function
}
});I was hoping to be able to call the method directly. But as @samccone pointed out to me, this isn't possible. I understand that behaviors are sandboxed and that rocks. I like it. But now I want a semantically meaningful way of executing the showLoader function.
In a chat with Sam, he gave me some options - and I don't like any of them. They all break semantics, and/or tightly couple the developer's brain to the knowledge of how behaviors are implemented in order to use events / triggerMethod to make it work.
I'm picky about semantics. They are important. I want a semantically meaningful way to do this.
What I really want is a mixin - by name and by semantics. But I don't know of an easy way to make that happen in Marionette, right now, and behaviors were the closes thing. So I'm trying to abuse behaviors.
What's a better way to do this? Or is there a semantically meaningful API that can be added to behaviors, to allow a method to call behavior methods?
FWIW, here's the IRC log from my chat w/ Sam
derickbailey
is there a way to make a behavior's method available on the view that is using the behavior?
samccone
like to call a behavior directly?
derickbailey
my behavior has a "showLoader" method on it
samccone
yep
derickbailey
i want to call "this.showLoader()" from within the view that is using the behavior
samccone
word the "way" to do it
samccone
would be to change showLoader to...
samccone
onShowLoader
samccone
and triggerMethod("showLoader")
samccone
on your view instance
derickbailey
ugly :-/ should have some kind of "exports" from the behavior to make method easily available on the view
derickbailey
but will do for now
samccone
then your view is tightly coupled to the view
derickbailey
i'm ok with that
samccone
we did this on purpose to force separation between behaviors and views
derickbailey
it's a mixin
samccone
"proxy bus"
samccone
it does not mutate the view class
samccone
this way you can stack and mix behaviors without worries about the view instance
derickbailey
yeah
derickbailey
but it limits the usefulness of behaviors for situations like this
samccone
the evented interface acts as your interface layer
derickbailey
it's just an unintuitive API and an unintended use of triggerMethod
derickbailey
it would be better to have a semantically meaningful API to work with the behaviors
samccone
open to ideas on it. also would be interested in seeing your use case.
derickbailey
ajax loader / spinner image
derickbailey
i want a re-usable "showLoader()" and "hideLoader()" method
derickbailey
behaviors seem like the perfect place to do it
samccone
direct invocations of behaviors seems like it could be not the best use for behaviors
derickbailey
maybe i'm abusing behaviors?
samccone
when do you want to show the loader
derickbailey
it varies
samccone
on some sync or fetch event on your model?
derickbailey
sometimes on a button click
samccone
ok
derickbailey
some times on model fetch
derickbailey
sometimes on ... whatever
samccone
seems likeeee an agnostic event on the view would be a great way to normalize it
samccone
that your behavior can react to
derickbailey
again, unintuitive api
derickbailey
and wrong semantics
derickbailey
i don't like this.trigger("show:loader")... that's a command, not an event
derickbailey
i'm picky about semantics
samccone
sure this.trigger("loading")
samccone
onLoading => ....
samccone
but you should file an issue
samccone
I am sure the team would love to present their use cases / approaches
derickbailey
yeah, there are plenty of "technically, it works" solutions... but not a clean one that i see
samccone
For me the the separation helps enforce behaviors
derickbailey
i agree... but now i want something more :)