noveogroup / backbone.iobind

Bind socket.io events to backbone models & collections. Also includes a drop-in replacement for Backbone.sync using socket.io.

Home Page:https://noveogroup.github.io/backbone.iobind/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Namespace problem with parsing

igorT opened this issue · comments

I have a user object with /user url and no collections. IO.sync does not set the namespace right as cmd[0] is empty and cmd[1 ] is equal to "user". I switched to do namespace = cmd[1 ] for now but expect problems in the future.

The current method assumes you are not using a leading '/' for your urlRoot or url for your Backbone models and collections, respectively. See the readme examples. As socket.io does not use or need a path in the tradition sense, slashes don't play into it.

Change your url from /user to just user and you should be able to use the io.sync replacement unmodified.

In my next set of fixes I will check for that as I could see this being an inconvenience if you are converting an ajax app to use socket.io, or only using it from some parts of your app. This is advertised as a "plug and play" replacement for Backbone.sync, as you know :)

I'll try and get to it over the weekend. Thanks!

Makes sense. Thanks

This problem also applies to ioBind method, which also assumes you have defined models and collections urls as functions.

Can you provide an example?

Of course. If you define a model like this:

var UserModel = Backbone.Model.extend({

  url: '/user',

  initialize: function(){
    this.ioBind('update', window.socket, this.serverChange, this);
  }

  serverChange: function(data){
    // ...
  }

};

There will be an error executing this.url() in this code extracted from model.js (and also applies to collection.js):

Backbone.Model.prototype.ioBind = function (eventName, io, callback, context) {
  var ioEvents = this._ioEvents || (this._ioEvents = {})
    , globalName = this.url() + ':' + eventName
    , self = this;

Checking if url is a function or a value doesn't solves the problem, because the model must listen to the events addressed to the model namespace which may not be its url (as in the case of this issue and solved in sync method).

Extracting the propper namespace from the model url (checking if it's defined as a function or as a value) would solve this problem.

Thank you (and excuse my english).

Ahh, I get what your trying to do now. The answer to this has already been addressed by Backbone itself. Model#url is actually a function defined by backbone.js and you should not overwrite it. Instead, use the urlRoot property to define your namespace. Then, the built in url function will build a namespaced string for you.

Here is the relevant info from Backbone's docs: http://documentcloud.github.com/backbone/#Model-url

I wrote the example on the fly and made that mistake, but that was not the main problem i was talking about. If you replace url property with urlRoot property in my example, then the function ioBind will get the correct url of the user /user/ID and the model will listen to events like /user/ID:update but the correct namespace is still user/ID and there will be addresses the events emitted by the server (like user/ID:update). So, the model of the example will sync correctly (because in that case the namespace is extracted properly from the url) but won't get the changes from the server.

Anyway, in the method ioBind of Backbone.Collection you assume that the url is defined as a value but it also can be defined as a function: http://documentcloud.github.com/backbone/#Collection-url