Ray
Ray

Reputation: 1828

Dojo store behaviour

I've started learning dojo and faced with very strange syntax in one project on GitHub.

  dojo.declare('app.services.Favorites', [ dojo.store.Memory ], {

    constructor : function() {
      this.inherited(arguments);

      dojo.subscribe('/favorites/add', dojo.hitch(this, 'put'));
      dojo.subscribe('/favorites/remove', this, function(person) {
        this.remove(person.id);
      });
    },

    put : function() {
      this.inherited(arguments);
      this._save();
    },

    remove : function() {
      this.inherited(arguments);
      this._save();
    },

    _save : function() {
      if (!storage) { return; }
      window.localStorage.setItem('favorites', JSON.stringify(this.data));
    }

  });

  // create an instance that overwrites the constructor
  app.services.Favorites = new app.services.Favorites({
    data : data ? JSON.parse(data) : []
  });

}()

Can anyone explain me what doesn't mean this part?

dojo.subscribe('/favorites/add', dojo.hitch(this, 'put'));
          dojo.subscribe('/favorites/remove', this, function(person) {

Upvotes: 0

Views: 103

Answers (1)

ajp15243
ajp15243

Reputation: 7952

This is using the Dojo Topic System, which is like a form of global events (and isn't tied to stores in any way).

Any code can publish a "topic" (just a string, often formatted like a URL or filesystem path to keep things looking organized/scoped), optionally with an object of data (or any number of additional arguments in newer Dojo versions). Note that Dojo 1.7 specifically can also use the dojo/connect module, but dojo/topic is recommended instead, especially in later versions.

// Dojo 1.7+
require(["dojo/topic"], function(topic){
    topic.publish("some/topic", "one", "two");
});

// Dojo 1.7 (AMD)
require(["dojo/_base/connect"], function(connect){
    connect.publish("foobar", [{
        item:"one", another:"item", anObject:{ deeper:"data" }
    }]);
});

// Dojo < 1.7
dojo.publish("foobar", [{
    item:"one", another:"item", anObject:{ deeper:"data" }
}]);

Other pieces of code can then subscribe to certain topics (again, with strings), and register a callback function with said subscription. Note again that Dojo 1.7 specifically can also use the dojo/connect module, but dojo/topic is recommended instead, especially in later versions.

// Dojo 1.7+
require(["dojo/topic"], function(topic){
    topic.subscribe("some/topic", function(){
        console.log("received:", arguments);
    });
});

// Dojo 1.7 (AMD)
require(["dojo/_base/connect"], function(connect){
    connect.subscribe("/foo/bar/baz", function(data){
        console.log("i got", data);
    });
});

// Dojo < 1.7
dojo.subscribe("/foo/bar/baz", function(data){
    console.log("i got", data);
});

When a topic is published, any subscribers to that topic (the publish and subscribe topic strings must match exactly) will be notified and have their callback functions executed. The optional data object (or all additional arguments) is passed to each of the callback functions if it was provided in the publish.

Note that creating a subscription after a publish event has occurred will not retroactively fire the subscription callbacks for the previous published event(s). Subscription callbacks are only fired at the moment a publish event happens.

This GitHub project looks to be using a very old version of Dojo given the use of dojo.subscribe (as opposed to using the dojo/topic module). It looks like Dojo 1.6, whereas the most recent Dojo version is 1.9. Dojo 1.7 introduced a lot of changes in how Dojo functionality is accessed and deprecated previous ways, and a lot of the old ways of doing it have been removed in 1.8 and 1.9.

Docs (with relevant Dojo versions):

I highly recommend using the latest Dojo version and hence using the dojo/topic module (which contains publish and subscribe methods), rather than using the deprecated dojo.publish and dojo.subscribe methods.

Example code taken from documentation links.

Upvotes: 1

Related Questions