peerigon / alamid

Framework for RESTful JavaScript web applications that run both on the server- and clientside.
http://www.alamidjs.com
MIT License
23 stars 3 forks source link

Fight the model jungle #201

Open jhnns opened 11 years ago

jhnns commented 11 years ago

The control flow of saving, fetching and destroying models is currently a total mess. Also the model is getting bigger and bigger. We need to split tasks and rework it.

First sketch

Explanations:

The model represents a collection of attributes that can be watched and changed. Thus the model can also be used to save specific states in views (without being something that must be serialized).

The resource is divided in a static- and instance-part.

Resource (static)

extends Model

extends EventEmitter

The service is responsible to read or write resources into a persistent data storage.

// services/post/CommentService.server.class.js

var CommentService = Service.extend("CommentService", {

    read: function (req, res) { ... },

    readCollection: function (req, res) { ... },

    create: function (req, res) { ... },

    update: function (req, res) { ... },

    destroy: function (req, res) { ... }

});

// registers listeners for io-events of that url on the api
CommentService.watch("blog/comment");

// remove listeners
CommentService.unwatch();
// client.init.js

// watch on Api for specific requests and start a http/websocket request
RemoteService.watch("blog/comment");

Questions

meaku commented 11 years ago

Seems like a lot of stuff to me :)

jhnns commented 11 years ago

It also seems useful to separate between raw data and a model instance. Sometimes it's more desireable to work on the raw data (especially if you don't need an EventEmitter or convenient methods like save(), fetch() or destroy().

One possible solution could be that the Resource will always emit and accept raw data in contrast to the Model. But the Resource provides a special link method to register a specific Modelclass for a model url and extends that Modelclass with convenient-methods like find, save, fetch, etc.

BlogResource.link(Blog);

// calls internally something like
Blog.find = function (ids, params, callback) {
    var req = new Request(ids, params),
        res = new Response();

    BlogResource.emit("readCollection", req, res);

    return res;
};
Blog.prototype.save = function () {
    var method = this.getId()? "create" : "update",
        req = new Request(this.getIds(), null, this.toObject()),
        res = new Response();

    BlogResource.emit(method, req, res);

    return res;
};
// and so on