Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using inheritance in meteor.js

I've been hoping to use inheritance in Meteor, but I couldn't find anything about it in the documentation or on Stack Overflow.

Is it possible to have templates inheriting properties and methods from another abstract template, or class?

like image 489
Romain Vergnory Avatar asked Nov 26 '12 15:11

Romain Vergnory


3 Answers

I think the short answer is no, but here's a longer answer:

One thing I've done to share functionality among templates is to define an object of helpers, and then assign it to multiple templates, like so:

var helpers = {
    displayName: function() {
        return Meteor.user().profile.name;
    },
};

Template.header.helpers(helpers);
Template.content.helpers(helpers);

var events = {
    'click #me': function(event, template) {
        // handle event
    },
    'click #you': function(event, template) {
        // handle event
    },
};

Template.header.events(events);
Template.content.events(events);

It's not inheritance, exactly, but it does enable you to share functionality between templates.

If you want all templates to have access to a helper, you can define a global helper like so (see https://github.com/meteor/meteor/wiki/Handlebars):

Handlebars.registerHelper('displayName',function(){return Meteor.user().profile.name;});
like image 154
zorlak Avatar answered Nov 16 '22 12:11

zorlak


I've answered this question here. While the solution doesn't use inheritance, it allow you to share events and helpers across templates with ease.

In a nutshell, I define an extendTemplate function which takes in a template and an object with helpers and events as arguments:

extendTemplate = (template, mixin) ->
  helpers = ({name, method} for name, method of mixin when name isnt "events")
  template[obj.name] = obj.method for obj in helpers

  if mixin.events?
    template.events?.call(template, mixin.events)

  template

For more details and an example see my other answer.

like image 32
Gezim Avatar answered Nov 16 '22 12:11

Gezim


Recently, I needed the same functionality in my app so I've decided to create my own package that will do that job out of the box. Although it's still work in progress, you can give it a go.

Basically, the entire method is as follows:

// Defines new method /extend
Template.prototype.copyAs = function (newTemplateName) {
    var self = this;

    // Creating new mirror template
    // Copying old template render method to keep its template
    var newTemplate = Template.__define__(newTemplateName, self.__render);
    newTemplate.__initView = self.__initView;

    // Copying helpers
    for (var h in self) {
        if (self.hasOwnProperty(h) && (h.slice(0, 2) !== "__")) {
            newTemplate[h] = self[h];
        }
    }

    // Copying events
    newTemplate.__eventMaps = self.__eventMaps;

    // Assignment
    Template[newTemplateName] = newTemplate;
};

In your new template (new_template.js) in which you want to extend your abstract one, write following:

// this copies your abstract template to your new one
Template.<your_abstract_template_name>.copyAs('<your_new_template_name>');

Now, you can simply either overwrite your helpers or events (in my case it's photos helper), by doing following:

Template.<your_new_template_name>.photos = function () {
    return [];
};

Your will refer to overwritten helper methods and to abstract ones that are not overwritten.

Note that HTML file for new template is not necessary as we refer to abstract one all the time.

Source code is available on Github here!

like image 1
Mike Grabowski Avatar answered Nov 16 '22 12:11

Mike Grabowski