marionettejs / backbone.wreqr Goto Github PK
View Code? Open in Web Editor NEWMessaging patterns for Backbone applications.
License: Other
Messaging patterns for Backbone applications.
License: Other
Hi guys,
Can we add the bower.json file to support new bower versions?
Thanks in advance!
It would be nice to get an exception letting you know that the handler
argument is not optional.
Currently, you get instead an Uncaught TypeError: Cannot read property 'apply' of undefined
when you try to invoke the command and it fails to execute the inexistent handler.
Hi,
In document, we can set multiple handlers in a single call.
But, can we execute multiple events in a single call ?
Thanks,
I just came across this and I completely agree. Are there plans to remove reqres? Please could somebody give a counter argument or explain a scenario of when reqres would benefit me. If this is the wrong place to put this, please point me in the right direction, thanks!
Support for multiple handlers under one name is currently not supported. Should be a nice improvement, since testing handlers (for example with sinonjs) override the existing handler.
// assuming app refers to an existing Backbone.Application
app.commands.setHandler('foo', BarCommand);
var spy = sinon.spy();
app.commands.setHandler('foo', spy);
app.execute('foo');
// assuming model is a refence to the model with is updated by BarCommand
expect(model.get('percentage')).toBeGreaterThan(0);
So the original set BarCommand is overriden with the spy, making executing multiple commands under one name impossible.
The latest fix needs to get published to npm @samccone
it's still depending on backbone 0.9.10, which really mucks with deployment and browserify.
I've also started running into this error :
node_modules/backbone.marionette/lib/core/amd/backbone.marionette.js:1627
this.vent = new Backbone.Wreqr.EventAggregator();
^
TypeError: Cannot read property 'EventAggregator' of undefined
The workaround right now is to delete the spurious dependency.
Among the three messaging systems of Wreqr, Commands stands out for its promise-like behavior. This is undocumented, but does work:
commands.execute('logIt');
// immediately executes the function
commands.setHandler('logIt', function() {
console.log('hello');
});
This is inconsistent with the other messaging systems, which ignore requests when they haven't been set up. I'm thinking that this should be removed from core and maybe moved to an external library, if anyone would want this functionality.
Hi Derek,
// Backbone.Wreqr, v0.0.0
// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
// Distributed under MIT license
// http://github.com/marionettejs/backbone.wreqr
Backbone.Wreqr = (function(Backbone, Marionette, _){
...
...
return Wreqr;
})(Backbone, Backbone.Marionette, _);
Just looking over this... is Marionette required here?
It's just an alias to Backbone.Events
... do we really need it? Wreqr's value is in the Command
and RequestResponse
.
Thoughts?
This is an enhancement proposal. It would be useful to be able to aggregate aggregators. For example, we have aggregator A, aggregator B, and aggregator C where aggregator C aggregates A and B. If an actor triggers an event on aggregator A, listeners to A and/or C will receive the event. If an actor triggers an event on aggregator B, listeners to B and/or C will receive the event. If an actor triggers an event on aggregator C, listeners to C will receive the event.
I'd like to hear your feedback and would be curious if others would find this useful.
The versions under lib/ in the bower package correspond to version 1.0.0, whereas the toplevel version corresponds to 1.3.1.
I don't quite understand why this is the case, as even listing the wreqr dependency as "[email protected]:marionettejs/backbone.wreqr#v1.3.1" doesn't seem to fix the situation. It keeps fetching an outdated version.
It will be more convient to be able to pass a hash into addHandler?
cmd.addHandler({
'foo': function () {...},
'bar': {
handler: function () {...},
context: this
}
});
Same problem as in Backbone.Babysitter, see the issue there.
This inaccuracy must be a blast from the past. jspm relies on the the package.json's main
attribute, which is set to lib\amd\backbone.wreqr.js
, but there is no folder lib\amd
. It should presumably read lib\backbone.wreqr.js
. In addition, the include
attribute contains a reference to lib\amd
as well.
Please update package.json!
I just know "use strict";
from ECMAScript 5: http://es5.github.com/#x14.1
Is "option strict"
a similar tag for some preprocessor or linter?
Hey folks,
This package has a strict dependency range for backbone but Backbone recently updated to 1.3.3
- is there any reason we can't bump the range to include the newer version?
Thanks
A common feature of messaging implementations is channels. Channels are a way to explicitly namespace communications in your application.
// Before
app.trigger('someModule:update');
app.trigger('anotherModule:update');
// After
var someModuleCh = Backbone.Wreqr.channel('someModule');
var anotherModuleCh = Backbone.Wreqr.channel('anotherModule');
someModuleCh.trigger('update');
anotherModuleCh.trigger('update');
Perhaps the most common use case for channels is having a global channel and a local channel for each component of your application.
A working implementation of this idea can be seen at Backbone.Wreqr-Radio.
As additional food for thought, the way that I use channels is to group things (or pieces) together into a thing called a Puppet. Each time a piece of a Puppet emits an event on its own personal Backbone.Events, it automatically gets forwarded to the local channel (with a prefix to prevent collisions). This lets me easily share events locally and globally through my applications with little effort.
Brainstorming Wreqr 2.0. Inspired by conversations with @cobbweb
setHandlers
. Give setHandler
that same functionalitycommands
and reqres
to be different from one anothercommands
and reqres
an analogous API to the Event AggregatorBackbone has a single function for attaching an event, or multiple events. It is on
. Making setHandler
behave in this same way makes the APIs more consistent.
The fact that the APIs have the same methods prevents you from attaching both of them directly to an object, which is awkward. Ref #22.
Because this is super useful
This was a bad idea to begin with. The point of messaging protocols is to be decoupled, and to not care if anything is set up. Simply using the protocol should never throw errors. Released as 1.1!
trigger
on, once, off
listenTo, listenToOnce, stopListening
order
obey, obeyOnce, stopObeying
reactTo (listenTo), reactToOnce(listenToOnce), stopReacting (stopListening)
request
respond (on), respondOnce (once), stopResponding (off)
respondFor, respondForOnce, stopRespondingFor
In short: I suspect that Wreqr and Babysitter is broken when using the requirejs optimizer.
Backbone introduced it's own shim in 1.1.1 and can be seen below. In short, what this does is that window. Backbone isn't set until first require of Backbone, which is done at runtime. This is all fine when running un-optimized, but when compiling with the requirejs optimizer, all files are concatenated, and window.Backbone will thus be undefined at parse time making "Backbone.Wreqr = (function(....." fail.
Any ideas on how to solve this?
Backbone 1.1.2 shim
(function(root, factory) {
// Set up Backbone appropriately for the environment. Start with AMD.
if (typeof define === 'function' && define.amd) {
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
// Export global even in AMD case in case this script is loaded with
// others that may still expect a global Backbone.
root.Backbone = factory(root, exports, _, $);
});
// Next for Node.js or CommonJS. jQuery may not be needed as a module.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore');
factory(root, exports, _);
// Finally, as a browser global.
} else {
root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
}
}(this, function(root, Backbone, _, $) {
A simple marionette requirejs config
require.config({
paths: {
"jquery": "lib/jquery-1.10.2.min",
"underscore": "lib/lodash.underscore.min",
"Backbone": "lib/backbone",
"Backbone.Wreqr": "lib/backbone.wreqr",
"Backbone.Babysitter": "lib/backbone.babysitter",
"Marionette": "lib/backbone.marionette"
},
shim: {
"underscore": {
exports: "_"
},
"Backbone": {
exports: "Backbone"
},
"Marionette": {
deps : [
"Backbone",
"Backbone.Wreqr",
"Backbone.Babysitter"
],
exports : "Backbone.Marionette"
},
"Backbone.Babysitter": {
deps: ["Backbone"],
exports: "Backbone.Babysitter"
},
"Backbone.Wreqr": {
deps: ["Backbone"],
exports: "Backbone.Wreqr"
}
}
});
require([
"Marionette"
], function (Marionette) {
});
Please keep backbone / jquery version dependencies in sync with backbone.marionette.
It's very important for those using npm like with browserify otherwise multiple backbone will be used and wreqr will be attached to one backbone, but marionette to another and marionette will have an undefined backbone.wreqr.
Ultimately, wreqr relies on all of the same methods underneath. The difference between them, from a programming perspective, is really just the API to access them. But the commands and reqres objects rely on methods with the same name to attach handlers.
This issue is about separating those out to be two separate handlers. I'm fine with them being the same thing beneath the hood, but there are benefits to making the API calls separate.
I want to do this because of the tendency for Backbone objects to attach the event aggregator directly to the object.
// It's like this
var myModel = new Backbone.Model();
myModel.trigger('someEvent');
// Not this
myModel.vent.trigger('someEvent');
I like this more direct approach to the messaging system. It makes it seem like you're communicating with the object itself.
You can't do the same thing with Wreqr, though. Extending the object with commands and reqres causes a conflict with the handler methods.
This could be resolved by changing the methods to use more specific terminology:
reqres.setRequest();
commands.setCommand();
This would allow you to do:
myObject.execute( 'someCommand' );
myObject.request( 'someRequest' );
Which is more preferable, and more in line with how Backbone handles events.
The only place where this would affect Marionette is the Application object, where we could optionally merge these directly into the app instead of having separate objects. In that case, though, I might prefer it as a separate object as it feels more like a 'channel' when it's separate.
In the third paragraph, the link titled 'our blog post' is a 404
http://marionettejs.github.io/2014/07/11/introducing-backbone-radio/index.html
It would be nice to be able to set multips handlers at once, like you can with listenTo as in this gist:
https://gist.github.com/mpolichette/5638783
If I find time, i'll get around to writing this and submitting a pull request :)
I understand why it might have been named this, but I find the naming .addHandler()
a bit confusing.
When I first looked at the wreqr readme, I would have assumed it might have worked like this:
var commands = new Backbone.Wreqr.Commands();
commands.addHandler("foo", function(){
console.log("first handler");
});
commands.addHandler("foo", function(){
console.log("second handler");
});
commands.execute("foo");
// first handler
// second handler
Obviously this isn't right because you can only have one handler for an event, but I still frequently double take when I read the addHandler()
name. Personally I would find something along the lines of setHandlerFor('foo', fn)
less confusing.
Just food for thought. Thanks!
We need to make sure that the shortcut API for running a commands doesn't return a value.
// This can't return a value
Backbone.Wreqr.radio.commands.execute( 'global', 'myCommand' );
Ref #41
Way too many people think that they should not use wreqr and or something is wrong with marionette since we are still using it.
the deprecation notice should be more like... This lib is feature locked, future message passing work is being done here: ...
maybe
sorry - have looked around
this is the closes I can find to any doco: marionettejs/backbone.marionette#402 (comment)
Mostly to fix the bower issue
Hi!
There might be a very good reason for that but why does neither Request or Command warn when it doesn't find the handler?
Something like:
if (this.hasHandler(name)) {
return this.getHandler(name).apply(this, args);
} else {
console.warn('Request handler not found: ' + name)
}
it would have saved me hours of silly debugging, like times I inadvertently request
a command
or vice versa.
Package.json is v1.3.4 but all contents of lib say 1.3.3. Led to some confusion when installing deps for Marionette. Not a huge deal since it's all going to be deprecated, but was confused as to how/why it happened.
Why? A few reasons.
So that's that.
Bye Wreqr ๐
When working with Wreqr's RequestResponse object, I noticed that there is no way to make a request, but also specify a default value in case there are no handlers for that request. If a handler for the request doesn't exist, we run into this code:
var config = this._wreqrHandlers[name];
if (!config) {
throw new Error("Handler not found for '" + name + "'");
}
It would be nice if we had the option of specifying a default value in case a handler for the request has never been registered. This could be implemented in a new method, such requestWithDefault
. I'd be more than happy to create a pull request if we think this is a good feature to have. I'm thinking something like:
requestWithDefault: function() {
var name = arguments[0];
var def = arguments[1];
var args = Array.prototype.slice.call(arguments, 2);
if (this.hasHandler(name)) {
return this.getHandler(name).apply(this, args);
} else {
return def;
}
}
Now updated after more research
I'm unable to write unit tests with Mocha/Chai involving Wreqr Commands objects because they are apparently cyclic structures. The cyclicity (is that a word?) comes from attaching handler:add
with this
as the context @ line17.
This results in:
x._events.handler:add[0].ctx._events.handler.add[0].ctx...
when x
is an instance of Commands.
To reproduce, simply write any unit test with Chai where the object you're testing is, or contains, a Wreqr Commands object. For instance, expect(commandsObject).to.equal( 'lalala' );
The fact that it can't even contain a Wreqr Commands instance is the real pain point here.
It might not be an issue that Wreqr can handle, but I'm going to look into it more before closing the issue.
'Nuff said.
I have Backbone.Marionette and Backbone.Wreqr. All tests worked fine with Marionette. When I added Wreqr (I use requirejs modules) then I have this problem:
PhantomJS 1.9.7 (Mac OS X) ERROR
ReferenceError: Can't find variable: Backbone
at /bower_components/backbone.wreqr/lib/backbone.wreqr.js:11
My karma config file:
files: [
{pattern: 'bower_components/jquery/jquery.min.js', included: false},
{pattern: 'bower_components/underscore/underscore-min.js', included: false},
{pattern: 'bower_components/backbone/backbone-min.js', included: false},
{pattern: 'bower_components/backbone.marionette/lib/backbone.marionette.js', included: false},
{pattern: 'bower_components/backbone.wreqr/lib/backbone.wreqr.js', include: false},
...
When I use amd version, path like this:
{pattern: 'bower_components/backbone.wreqr/lib/amd/backbone.wreqr.js', include: false}
Then I see this error:
Error: Mismatched anonymous define() module: function (_, Backbone) {
...
...
I have problem only with tests. Application works fine in browser using amd backbone.wreqr.
Thanks for any tips/help.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.