ractivejs/ractive — pull request #1594 by Rich-Harris (2014-12-18 22:01:35+00:00)
Title: Experiment: removing ractive.data

**not ready for merge**

This is an experiment that follows #1590 - [no-data](https://github.com/ractivejs/ractive/tree/no-data) is a branch off of [viewmodel](https://github.com/ractivejs/ractive/tree/viewmodel). It follows the thought therein to its logical conclusion - what happens if we get rid of `ractive.data` altogether?

Hear me out:

* There's an API for getting/setting data - doing `foo = ractive.data.foo` or `ractive.data.foo = 'bar'` is a hack, and always has been
* `ractive.data` doesn't know anything about computed properties and mappings, whereas `set()` and `get()` do
* If we remove `ractive.data` (while continuing to offer a means of doing the various things that `ractive.data` used to do), we can remove a decent chunk of code, ward off tricky edge cases (e.g. #1548), and make things simpler for people learning Ractive
* Therefore we should do it

Obviously that's contingent on not losing essential functionality, but I don't (yet) see any reason why we should.

## Magic mode

Magic mode should continue to work:

```js
var model = { name: 'Alice' };

var ractive = new Ractive({
el: 'body',
template: 'hello {{name}}',
data: model
});

// this won't work...
ractive.data.name = 'Bob';

// ...but this would
model.name = 'Bob';
```

## Initialisation functions

This relates to #1413. Instead of doing this...

```js
Widget = Ractive.extend({
template: '{{message}}',
data: function ( d ) {
d.message = 'the answer is ' + d.answer;
}
});

var ractive = new Widget({
el: 'body',
data: { answer: 42 }
});
```

...you'd do this:

```js
Widget = Ractive.extend({
template: '{{message}}',
data: function () {
return {
message: 'the answer is ' + this.get( 'answer' );
};
}
});

var ractive = new Widget({
el: 'body',
data: { answer: 42 }
});
```

To my mind that's a better approach anyway - it's more consistent with how things work everywhere else, and it means you're not mutating someone else's object. Obviously there's a little bit of juggling involved to get things into a state where `this.get()` does something other than throw an error or cause an infinite loop, but it's totally possible.

---------

Will continue to work on this, and see if it is actually possible to replace all the existing functionality without having `ractive.data`. (In modern browsers, we could have a lazy accessor that returns the result of `ractive.get()` and prints a deprecation warning. Wouldn't work in IE8, but since no-one is using that as their dev browser, anyone affected would see the warning.) Anyone have any thoughts in the meantime - any reason why this would actually be a terrible idea?