component / reactive

Tiny reactive template engine
382 stars 48 forks source link

Reactive should interpolate functions #154

Open ooflorent opened 10 years ago

ooflorent commented 10 years ago

Reactive should be able interpolate functions. The above suite tests <div>{ ret("foo") }</div> when ret is defined in the model or the view. Only this.ret seems to work.

Here I'm testing ways to declare the function:

var assert = require('assert');
var domify = require('domify');
var reactive = require('reactive');

describe('Model function', function() {
  it('this.fn()', function() {
    var el = domify('<div>{ this.ret("foo") }</div>');
    var view = reactive(el, {ret: String});
    assert('foo' == el.textContent);
  });
  it('fn() with fn: String -> String', function() {
    var el = domify('<div>{ ret("foo") }</div>');
    var view = reactive(el, {ret: String});
    assert('foo' == el.textContent);
  });
  it('fn() with fn: -> (String -> String)', function() {
    var el = domify('<div>{ ret("foo") }</div>');
    var view = reactive(el, {ret: function() { return String }});
    assert('foo' == el.textContent);
  });
});

describe('View function', function() {
  it('fn() with fn: String -> String', function() {
    var el = domify('<div>{ ret("foo") }</div>');
    var view = reactive(el, {}, {delegate: {ret: String}});
    assert('foo' == el.textContent);
  });
  it('fn() with fn: -> (String -> String)', function() {
    var el = domify('<div>{ ret("foo") }</div>');
    var view = reactive(el, {}, {delegate: {ret: function() { return String }}});
    assert('foo' == el.textContent);
  });
});

Result

 Model function
    ✓ this.fn()
    2) fn() with fn: String -> String
    3) fn() with fn: -> (String -> String)

  View function
    4) fn() with fn: String -> String
    5) fn() with fn: -> (String -> String)

The last 4 tests raise an error:

// Uncaught TypeError: object is not a function VM2169:3
(function(reactive
/**/) {
return ['ret']('foo') 
})
ooflorent commented 10 years ago

Any update about this? We (at @ebuzzing) are using reactive in a new product and and really need this nasty bug to be fixed. cc @defunctzombie

defunctzombie commented 10 years ago

So the gist of this is that function calls without this. don't work?

ooflorent commented 10 years ago

Yes. Even if the function is defined into the view delegate object.

chemzqm commented 8 years ago

I've tried to add

  //add this to function call
  expr = expr.replace(/([^\.]|^)\b[0-9a-zA-Z_$]+?\(/g, function(_, s) {
    if (s.length === 0) {
      return 'this.' + _;
    } else {
      return _[0] + 'this.' + _.slice(1);
    }
  })

this into https://github.com/component/reactive/blob/master/lib/utils.js#L89 to make this before function call optional.