ripplejs / ripple

A tiny foundation for building reactive views
http://ripplejs.github.io
1.28k stars 66 forks source link

Emit an event when a view is created #1

Closed queckezz closed 10 years ago

queckezz commented 10 years ago

I'm not sure if this is the correct way to do it but I didn't found another solution. This basically allows manipulating the view object when a new Ripple instance is created:

Ripple.on('construct', function (View) {
})

Maybe construct is not the best name and I should have called it instance or something. This would also allow ripple-router#34 to work.

What do you think?

anthonyshort commented 10 years ago

That's actually how it works currently :)

https://github.com/ripplejs/view/blob/master/index.js#L33

If you've got any ideas about the API I'm definitely up for improving it! I wasn't sure if the construct event was too gross to do view setup. I was considering doing it the way React does it and calling methods. So if View.prototype.initialize exists, it could just call that.

queckezz commented 10 years ago

Yeah but you can hook into this event only from the view module. Like this:

var View = ripple()
  .use(function (ripple) {
    Ripple.on('construct', ...) // doesn't work
  })
  .compile(tmpl)

var view = View()
  .use(function (View) {
     View.on('construct', ...) // Works
  })

The problem comes in when you want to create a plugin that adds attributes and additional functions for a view. Right now you need to do something like this:


var View = ripple()
  .use(plugin.ripple)
  .compile(tmpl)

var view = View()
  .use(plugin.view)

It would be much simpler if we could use() a plugin once and be able to access both, Ripple and View.

I'm not sure API-wise to be honest, but I guess it doesn't really matter if we use events or calling methods like react does.

anthonyshort commented 10 years ago

Yeah that's a really good point. I'll have a think about it. I was considering changing up the way the Compiler and the View interact, but you're definitely right, you need a single .use method.

I'd be happy if Ripple emitted compile event and passed in the view like you've got there.

ripple()
  .on('compile', function(View){})
  .compile(template);

The change I was thinking about making was switching it to this:

var View = ripple(template) // returns a view with the compiler added

View.use(function(){
    // this === View
    // this.compiler is the Compiler instance 
});

View.addAttribute();
View.addComponent();

var view = new View();

It's a subtle change, and I need to make sure it's still easy to create sub-views and components this way, but it means there would be a single .use and you know you're always getting back a view.

queckezz commented 10 years ago

Yep, I really like that, makes much more sense in my eyes. So you would completely dump View.on('construct')? To be honest, I don't really get it why you need to do this internally anyways:

  View.filter = function(name, fn) {
    View.on('construct', function(view){
      view.filters[name] = fn;
    });
    return this;
  };

instead of just:

  View.filter = function(name, fn) {
    View.filters[name] = fn;
    return this;
  };
anthonyshort commented 10 years ago

Haha good point. That's me just being stupid really. That's another fix I'll make. I'm about to push some of these changes up.

queckezz commented 10 years ago

Nice, took a brief look at the changes. Much easier now for creating plugins.