Git Product home page Git Product logo

domchanger's Introduction

DomChanger

Join the chat at https://gitter.im/creationix/domchanger

This is a small library that lets your build react.js style websites, but with minimal dependencies and using JSON-ML style syntax instead of JSX.

A Simple Component

DomChanger components are simply functions that export a given interface. The main export is a render() function that takes input data and returns what to display. HTML nodes are described using JSON-ML syntax.

// Defining the component
function HelloMessage() {
  return { render: render };
  function render(name) {
    return ["div", "Hello " + name];
  }
}

// Creating a instance attached to document.body
var instance = domChanger(HelloMessage, document.body);
// Send in the initial data to render.
instance.update("Tim");

You can also instance.destroy() when you're done with the component and wish to destroy it.

A Stateful Component

In addition to taking input data (accessed via update arguments), a component can maintain internal state data (accessed via local variables in the closure). A component can call refresh when it's state has been changed.

function Timer(emit, refresh) {
  var secondsElapsed = 0;
  var interval = setInterval(tick, 1000);
  return {
    render: render,
    cleanup: cleanup
  };
  function render() {
    return ["div", "Seconds Elapsed: ", secondsElapsed];
  }
  function tick() {
    secondsElapsed++;
    refresh();
  }
  function cleanup() {
    clearInterval(interval);
  }
}

An Application

Using update data and closure state, we can put together a small Todo application. This example uses state to track the current list of items as well as the text that the user has entered.

function TodoApp(emit, refresh) {
  var items = [], text = "";

  return { render: render };

  function render() {
    return ["div",
      ["h3", "TODO"],
      [TodoList, items],
      ["form", { onsubmit: handleSubmit },
        ["input", {
          onchange: onChange,
          value: text
        }],
        ["button", "Add #", items.length + 1]
      ]
    ];
  }

  function handleSubmit(evt) {
    evt.preventDefault();
    items.push(text);
    text = "";
    refresh();
  }

  function onChange(evt) {
    text = evt.target.value;
  }
}

function TodoList() {
  return { render: render };
  function render(items) {
    return ["ul", items.map(function (itemText) {
      return ["li", itemText];
    })];
  }
}

Live Example

You can play around with a larger example in this fiddle.

<iframe src="http://jsfiddle.net/BsUDE/3/embedded/js,result/"></iframe>

domchanger's People

Contributors

alessioalex avatar creationix avatar gitter-badger avatar redunta avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

domchanger's Issues

cleanup not called when updating/refreshing

Hey,
I have found an issue that cleanup will not be called though a component will be removed from the tree and replaced with a new one (same type but new instance)

please have a look at some sample code: http://jsfiddle.net/BsUDE/9/

In the output it should be 1,2 not 0,2

this can cause leaking of resources (eg if I would setInterval in the component)

Server-side render

Hello. Your library looks stunning minimalist. I would like to try to use it in one of my works, but I need to be able to get a static html-code as a string on the server. Is it possible?

after render hook?

Hi,

How would you suggest to handle a case when you need to interact programatically with an element or component after it is rendered. For example rendering a <textarea> with a value and setting the cursor position or selection range within it after it has been rendered?

Is there a post-render hook that provides a reference to the element's node to allow for this?

thanks!

more isolated/stateful components

split from #4

IMO, there are a couple issues with components.

  1. render is called as both a pseudo-constructor to inject params into the component's closure as well as a refresh re-renderer.

  2. Components are not instanced, so no reference to them exists, this prevents exposure of any public api. eg not possible:

    return {
       render: render,
       someAPIMethod: foo,
       somePublicProp: bar,
    }
    
  3. Pre-instantiated components cannot be provided into a tree.

  4. The top-level .update() method acts as a constructor for the entire component tree and must accept params for all its sub-components.

For 1, maybe expose a render: and separate init:.
For 2, creating instances will allow for an API to be exposed for each component.
For 3, components can be externally created using their own inits and inserted into their parents via the parent's init (dep injection).
For 4, should be a non-issue if the others are implemented.

I don't know how much of this is do-able and would bloat/complicate the framework, so consider these wishes :)

diffing bug?

Hi @creationix,

In the example (and fiddle), if you check, then uncheck "Only show products in stock", console gives TypeError: Argument 1 of Node.appendChild is not an object. (domchanger.js, line 157). iPhone 5 doesn't re-render at all and Basketball re-renders under Electronics.

Looks like a diffing strategy error?

thanks!
Leon

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.