crysalead-js / dom-layer

Virtual DOM implementation.
MIT License
30 stars 1 forks source link

patching, children BANG! BANG! #59

Closed ghost closed 9 years ago

ghost commented 9 years ago

Hi! Your code BANG! too much for me now. I figure out I need to create array, right? But just testing this, and BANG! BANG! BANG!

I also ran into something called "infinity loop" I figured after study google for awhile. Is this normal or what??

Let us say count is a number that increasing and you do this. Then BANG!!

function render(count) { 
    return new domLayer.Tag("div", {
    }, [count]);
}

Here is what I got:

60
TypeError: fromStartNode.match is not a function
} else if (fromStartNode.match(toStartNode)) {

There is more BANG!! Look at this and try

// Ex 1
function render() {  
    return new domLayer.Tag("div", {}, "hello");
}
// Ex 2
function render(count) { 
    return new domLayer.Tag("div", {}, ["hello"]);
}

Will throw in the console:

TypeError: nodes[i].render is not a function
container.appendChild(nodes[i].render(parent));
jails commented 9 years ago

As I said in the documentation.This library is a low level library. You should build your own abstraction on top of it instead of trying to use it directly because the verbose syntax is prone to errors.

For example in virtual-dom there's an hyperscript function. But I didn't enforce such abstraction since such abstraction highly depends on the higher level of abstraction you want to acheive (e.g a component layer). So letting people to create their own hyperscript function on top of the existing one doesn't make sense. Better to let them create their hyperscript function directly.

The error nodes[i].render is not a function means something in your virtual tree can't be rendered (i.e. is not a virtual node)

function render() {  
    return new domLayer.Tag("div", {}, "hello");
}

Is invalid, since the third parameter needs to be an array and:

function render() {  
    return new domLayer.Tag("div", {}, ["hello"]);
}

can't work either since "hello" is not a virtual node, it's just a string and therefore doesn't have any .render() method.

The correct syntax is:

new domLayer.Tag("div", {}, [new domLayer.Text("hello")]);

And for example bellow is the hyperscript function I'm using for writing specs:

function h(context, children) {
  var context = context || {};
  var children = children || [];

  if (typeof context === "string") {
    return new Text(context);
  }
  var tagName = (context.tagName || "div").toLowerCase();
  delete context.tagName;

  return new Tag(tagName, context, children.map(function(value, key) {
    if (typeof value === "string") {
      return new Text(value);
    }
    return value;
  }));
}

So you can write directly:

h({ tagName: "div" }, ["hello"])

But all higher level of abstraction is up to you.