Giter Site home page Giter Site logo

backbone.wreqr's People

Contributors

ahumphreys87 avatar aki77 avatar chrisronline avatar foliosus avatar hashchange avatar jamesplease avatar jamiebuilds avatar jasonlaster avatar justblackbird avatar kis avatar krismeister avatar marcelklehr avatar megawac avatar paulfalgout avatar samccone avatar scott-w avatar sontek avatar wbinnssmith avatar zerkalica avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

backbone.wreqr's Issues

`setHandler` is not checking if a handler is actually provided

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.

Execute multiple events .

Hi,

In document, we can set multiple handlers in a single call.
But, can we execute multiple events in a single call ?

Thanks,

reqres, why?

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!

Setting multiple handlers under one name

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.

upgrade backbone.wreqr npm package

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.

Remove promise-like behavior from Commands

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.

Remove EventAggregator

It's just an alias to Backbone.Events... do we really need it? Wreqr's value is in the Command and RequestResponse.

Thoughts?

Ability to aggregate aggregators

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.

Bower version 1.3.1 contains 1.0.0 build

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.

Extend addHandler to use hash?

It will be more convient to be able to pass a hash into addHandler?

        cmd.addHandler({
                'foo': function () {...},
                'bar': {
                    handler: function () {...},
                    context: this
                }
            });

Incorrect package.json main entry point (path does not exist in repo)

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!

New Feature: Channels

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.

Wreqr 2.0

Brainstorming Wreqr 2.0. Inspired by conversations with @cobbweb

Goals

  • Separate out the different protocols to have three separate APIs (#22)
  • Align the APIs with Backbone's current event API

  • Get rid of setHandlers. Give setHandler that same functionality
  • Rename the API of commands and reqres to be different from one another
  • Give commands and reqres an analogous API to the Event Aggregator
  • Stop throwing errors when handlers don't exist. wtf?

Justifications

Getting rid of setHandlers

Backbone 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.

Renaming the API of commands/reqres

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.

Give commands/reqres listenTo functionality

Because this is super useful

No more errors

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!

Possible nomenclature

Event Aggregator

trigger
on, once, off
listenTo, listenToOnce, stopListening

Commands

order
obey, obeyOnce, stopObeying
reactTo (listenTo), reactToOnce(listenToOnce), stopReacting (stopListening)

RequestResponse

request
respond (on), respondOnce (once), stopResponding (off)
respondFor, respondForOnce, stopRespondingFor

//cc @cobbweb @samccone

Wreqr (and Babysitter) broken in AMD setup with Backbone >= 1.1.1

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 publish this version

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.

Separate commands/reqres handler API

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.

.addHandler method name a bit confusing

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!

Add tests for proxied Commands

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

Reword notice that this lib will be replaced with radio

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

Request or Command not found fails silently

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.

Version number inconsistency

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.

Deprecate this library for Backbone.Radio

Backbone.Radio

Why? A few reasons.

  1. A new name is in order. Ironically, the real draw of Wreqr is that it's semantic but it has such a nonsensical name! I, myself, was turned away from Wreqr when I first came to this repository, because I just wasn't sure what the heck it was for. When newcomers read 'radio' they will immediately know what's going on, I think.
  2. There are big changes that need to come to this library.
  3. Deprecating the library gives people time to migrate over.

So that's that.

Bye Wreqr ๐Ÿ‘‹

Allow for a default value in Wreqr#request

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;
  }
}

Wreqr.Commands are cyclic structures

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.

Problem with testing (karma/phantomjs)

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.