HallM / jsframework

0 stars 0 forks source link

Compose-able and Extendable ViewModels #3

Open HallM opened 8 years ago

HallM commented 8 years ago

Could be a great idea for a ViewModel to compose or extend another ViewModel. Would remove the need for the "layout" field. As such, some ViewModels may not have a route. Their fetchers would not be directly executed, but instead executed by other ViewModel fetchers.

Extendable:

Compose-able:

Multi??:

HallM commented 8 years ago

Potential API:

'use strict';

var Bluebird = require('bluebird');

var layout = ViewModel({
  // no url, page title, just the view
  // this isn't a page we access, it's something we extend/include

  view: {
    file: require('../views/Layout')
    // props default to the thing returned from the Promise in the fetch()
  },
  fetch: function() {
    // fetch maybe like header, or sidebar, footer, whatever stuff
    return Bluebird.resolve({header: 'I am header', sidebar: 'action item', footer: 'something statically dynamic!'});
  }
});

var reuseable = ViewModel({
  // same thing. no page title or url things if not a full page

  view: {
    file: require('../views/Reusable'),
  },
  fetch: function() {
    return Bluebird.resolve({foo: 'bar'});
  }
});

var subpage = ViewModel({
  // but, it could be a full page as a subpage too!
  url: '/mypage',
  pageTitle: 'Hello page!',

  view: {
    file: require('../views/Subpage'),
  }
});

ViewModel({
  extend: layout,
  url: '/',
  pageTitle: 'Hello world!',

  view: {
    file: require('../views/Hello'),
    props: {world: 'world(default)'}
  }
});

ViewModel({
  extend: layout, // extend may not be the best word. "parent" may be more appropriate to describe, but eh
  include: [reuseable, subpage], // array, so we can have many children. could be not array for just one thing.

  url: '/secondPage',
  pageTitle: 'The ultimate page',

  view: {
    file: require('../views/Page2')
  },
  fetch: function() {
    return Bluebird.resolve({hello: 'world'});
  }
});

Subpages with children/includes and parent/extended-from may need to bring those along too. But maybe there's situations a user doesn't want to.

HallM commented 8 years ago

Just to add some more notes/thoughts:

render() {
  return (
    <MyLayout>
      <div>my stuff</div>
    </MyLayout>
  );
}