Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functions outside data #956

Closed
fskreuz opened this issue Jul 9, 2014 · 10 comments
Closed

Functions outside data #956

fskreuz opened this issue Jul 9, 2014 · 10 comments

Comments

@fskreuz
Copy link
Contributor

fskreuz commented Jul 9, 2014

In this example, the function that alters the array is inside data.

var ractive = new Ractive({
  el: output,
  template: template,
  data: {
    superheroes: xmen,
    sort: function ( array, column ) {
      array = array.slice(); // clone, so we don't modify the underlying data

      return array.sort( function ( a, b ) {
        return a[ column ] < b[ column ] ? -1 : 1;
      });
    },
    sortColumn: 'name'
  }
});

However, if I did something that would alter sort, it will run over sort in the data and would break the template. See this demo. Same happens when using reset, which I often use to clear off stuff, especially when reusing modals (clear, dump data, show).

Would it be better if these "helper" functions were separate from the data? Like a helpers per instance, and helpers in global, similar to partials.

var test = new Ractive({
  helpers : {
    foo : function(){...}
  }
});

Ractive.helpers.foo = function(){...}
@lburgess
Copy link

lburgess commented Jul 9, 2014

+1

... although in this scenario I have been known to use a computed property, when appropriate..

var ractive = new Ractive({
  el: output,
  template: template,
  data: {
    superheroes: xmen,
    sortColumn: 'name'
  }
  ,computed: {
    sortedSuperHeroes: function(){
      return this.sort(this.get('superheroes'), this.get('sortColumn'));
    }
  , sort: function ( array, column ) {
      array = array.slice(); // clone, so we don't modify the underlying data

      return array.sort( function ( a, b ) {
        return a[ column ] < b[ column ] ? -1 : 1;
      });
    }
});

@fskreuz
Copy link
Contributor Author

fskreuz commented Jul 9, 2014

Oh yeah, I forgot about computed. Hmm... Will look into that.

@Rich-Harris
Copy link
Member

The tutorial was written before computed properties were supported - I'd say they're probably a better solution in this case.

Another way to go would be to take advantage of the fact that data is 'inherited' - each instance's data object inherits from its constructor's prototype's data object. In the simplest case, that means you can add helpers to Ractive.prototype.data, and they will be accessible by all instances - but if those instances reset(), the helpers are still available.

Ractive.prototypes is aliased as Ractive.defaults, for historical (and aesthetic!) reasons. So you can do

var helpers = Ractive.defaults.data;

helpers.sort = function ( array ) {...};
helpers._ = _; // use underscore/lodash in templates

Here's a demo fiddle.

@martypdx
Copy link
Contributor

martypdx commented Jul 9, 2014

helpers._ = _;

@Rich-Harris I don't why, but it never occurred to me that you could set an object in data then call its methods in expressions. With those array sugar libraries you get in-template one-liner expressions. Very powerful.

@fskreuz
Copy link
Contributor Author

fskreuz commented Jul 9, 2014

@Rich-Harris I did notice that prototype action with subclassing. Reset a child, the parent values shine through. Interesting.

@martypdx
Copy link
Contributor

martypdx commented Jul 9, 2014

Reset a child, the parent values shine through.

@fskreuz Yes, the data is "re-configured" on reset.

@kurdin
Copy link

kurdin commented Jul 9, 2014

This is a very cool helpers._ = _;
It would be even cooler and easy to be able use | to separate different helpers/filters in templates
Instead of this:

    <h2>Sorted numbers reversed</h2>
    <p>{{ _(sort(numbers)).reverse() }}</p>

do this:

    <h2>Sorted numbers reversed</h2>
    <p>{{ sort(numbers) | _(data).reverse() }}</p>

@fskreuz
Copy link
Contributor Author

fskreuz commented Jul 9, 2014

The chained notation will do fine. Besides, they're standard JS syntax. The pipe looks Django-ish and foreign to JS.

@Rich-Harris
Copy link
Member

@martypdx @kurdin Yeah, it's handy! We should probably make mention of it in the docs/tutorials, as it's not obvious that you can do that.

I'm with @fskreuz on the syntax - if we introduce non-JS syntax it introduces a load of complexity, both for the library and for people using it.

Are we okay to close this issue?

@fskreuz fskreuz closed this as completed Jul 10, 2014
@fskreuz
Copy link
Contributor Author

fskreuz commented Jul 10, 2014

Closed :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants