MDV or markup as data

101 views
Skip to first unread message

ed.eu...@gmail.com

unread,
Sep 18, 2013, 3:05:58 PM9/18/13
to polym...@googlegroups.com
Hi,
Just looking at polymer, looks very interesting.

I've a question regarding building out the UI.

For me I feel that I should be using MDV, it feels more natural to me. Another alternative is to have the markup define the data.

Here is a sample of what I mean:


 <!-- MARKUP AS DATA -->
    <polymer-element
      name="md-choose" attributes="prompt modelId" extends="base-choose">
      <template>
        <label>{{prompt}}</label><br/>
        <content></content>
        <button on-click="printModel">Print model</button>
      </template>
      <script type="text/javascript">
        Polymer('md-choose');
      </script>
    </polymer-element>


    <!-- MDV -->
    <polymer-element
      name="mdv-choose" attributes="prompt modelId" extends="base-choose">
      <template>
        <label>{{model.prompt}}</label><br/>
        <template repeat="{{ model.choices }}">
          <q-choice
            id="{{id}}"
            on-click="selectItem"
            checked="{{isSelected}}">{{value}}</q-choice>
        </template>
        <button on-click="printModel">Print model</button>
      </template>
      <script type="text/javascript">
        Polymer('mdv-choose');
      </script>
    </polymer-element>

<!-- instantiate them -->
<mdv-choose modelId="data-model"></mdv-choose>
   
<md-choose modelId="data-model" prompt="What is 1 + 1">
      <q-choice
        id="0"
        checked="{{choices[0].isSelected}}">1</q-choice>
      <q-choice
        id="1"
        checked="{{choices[1].isSelected}}">2</q-choice>
</md-choose>

There are 2 elements: mdv-choose and md-choose.

mdv-choose - uses a template repeater to build the ui from the model.
md-choose tries to build out the behaviour from the node contents.

Note that md-choose doesn't work, but its there to illustrate the question. 

Would one ever want to build out the UI like its done in md-choose? If so is it possible?

Seth Ladd

unread,
Sep 18, 2013, 5:16:11 PM9/18/13
to ed.eu...@gmail.com, polymer-dev
Wow, good timing. I had the same email and thoughts in the works. If I may, let me ask the question in a similar way:

The Polymer TodoMVC example looks like this:

<td-todos modelId="model"></td-todos>

But I was expecting it to look like this:

<todo-app>
  <todo-item done>Learn Polymer</todo-item>
  <todo-item>Make the web awesome</todo-item>
</todo-app>

Why doesn't Polymer embrace the Light DOM more? Everything is in shadow dom, and as such as are hiding the semantic structure of the app.

I want binding between my code data model and my DOM tree (when appropriate, like above). Should we not try to embrace the DOM more? I want to right click on a future email app and see this:

<email-app>
  <message>
    <subject>...</subject>
    <to>sadfadf</to>
  </message>
</email-app>

Instead of:

<email-app>

Thoughts?


Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

John Messerly

unread,
Sep 18, 2013, 6:20:49 PM9/18/13
to Seth Ladd, ed.eu...@gmail.com, polymer-dev
On Wed, Sep 18, 2013 at 2:16 PM, Seth Ladd <seth...@google.com> wrote:
Wow, good timing. I had the same email and thoughts in the works. If I may, let me ask the question in a similar way:

The Polymer TodoMVC example looks like this:

<td-todos modelId="model"></td-todos>

But I was expecting it to look like this:

<todo-app>
  <todo-item done>Learn Polymer</todo-item>
  <todo-item>Make the web awesome</todo-item>
</todo-app>

Why doesn't Polymer embrace the Light DOM more? Everything is in shadow dom, and as such as are hiding the semantic structure of the app.

I want binding between my code data model and my DOM tree (when appropriate, like above). Should we not try to embrace the DOM more? I want to right click on a future email app and see this:

<email-app>
  <message>
    <subject>...</subject>
    <to>sadfadf</to>
  </message>
</email-app>

Instead of:

<email-app>

Thoughts?

It does look nice. Some thoughts that come to mind for me:
  • What would data binding look like in these examples?
  • Is it possible to fetch the data from the server and/or local storage?
  • How does the memory cost and access time of data-in-DOM compare to data-in-JavaScript-heap?
  • Is it a problem that the Model is being mixed up in the View tree?

Seth Ladd

unread,
Sep 18, 2013, 6:47:35 PM9/18/13
to John Messerly, ed.eu...@gmail.com, polymer-dev
On Wed, Sep 18, 2013 at 3:20 PM, John Messerly <jmes...@google.com> wrote:
On Wed, Sep 18, 2013 at 2:16 PM, Seth Ladd <seth...@google.com> wrote:
Wow, good timing. I had the same email and thoughts in the works. If I may, let me ask the question in a similar way:

The Polymer TodoMVC example looks like this:

<td-todos modelId="model"></td-todos>

But I was expecting it to look like this:

<todo-app>
  <todo-item done>Learn Polymer</todo-item>
  <todo-item>Make the web awesome</todo-item>
</todo-app>

Why doesn't Polymer embrace the Light DOM more? Everything is in shadow dom, and as such as are hiding the semantic structure of the app.

I want binding between my code data model and my DOM tree (when appropriate, like above). Should we not try to embrace the DOM more? I want to right click on a future email app and see this:

<email-app>
  <message>
    <subject>...</subject>
    <to>sadfadf</to>
  </message>
</email-app>

Instead of:

<email-app>

Thoughts?

It does look nice. Some thoughts that come to mind for me:
  • What would data binding look like in these examples?

I'd probably want a slick way to wire up mutation observer events to my custom element. We have this API now, but it requires a lot of work on my end to listen for child insertions or removals and then imperatively add or remove objects from my data model.
 
  • Is it possible to fetch the data from the server and/or local storage?

Assuming I have bindings between child DOM nodes and my data model, I'm hoping data persistence just kinda works. 
  • How does the memory cost and access time of data-in-DOM compare to data-in-JavaScript-heap?
I'm assuming/hoping that there's data binding between child nodes in light dom and my data-in-JavaScript. This can be kept in sync much like how template bindings keep things in sync today.
 
  • Is it a problem that the Model is being mixed up in the View tree?
Is there a difference? :)  I do want more of the semantic structure of my app to appear in the light dom. But this is the philosophical question I have for this group.

John Messerly

unread,
Sep 18, 2013, 8:04:21 PM9/18/13
to Seth Ladd, ed.eu...@gmail.com, polymer-dev
Right now the light DOM relates to the shadow DOM via the `<content>` element and its optional "select" attribute. I can't see how MutationObservers come into play?
  • Is it possible to fetch the data from the server and/or local storage?
Assuming I have bindings between child DOM nodes and my data model, I'm hoping data persistence just kinda works. 
  • How does the memory cost and access time of data-in-DOM compare to data-in-JavaScript-heap?
I'm assuming/hoping that there's data binding between child nodes in light dom and my data-in-JavaScript. This can be kept in sync much like how template bindings keep things in sync today.

If I am understanding, it sounds like you still want your data in JavaScript objects, but you also want it to be two way mirrored in the DOM tree. Does that sound right? What purpose does that serve? Is the idea to use HTML as a serialization language? It seems to me that the trend on the web has been in the other direction: moving away from XML towards JSON. And I worry there will be a lot of problems trying to keep the JS object graph in sync with the DOM object tree, leading to potential inconsistency and race conditions.

By contrast, in the case of template bindings, you're using a subset of the data model to drive creation of the view tree, which then can contain more details that aren't present in the model. The two trees** have different structure, and that's the entire point of the data-binding pattern. You can express the data structure optimally in your model objects, and you can express the DOM structure optimally in your templates+custom elements.

** caveat: models in the heap are not necessarily single-parent trees; they can be DAGs or DCGs depending on the needs of the app. This is another potential issue with trying to sync an object graph and the DOM.
  • Is it a problem that the Model is being mixed up in the View tree?
Is there a difference? :)  I do want more of the semantic structure of my app to appear in the light dom. But this is the philosophical question I have for this group.

In short: yes. In my humble opinion, the model-view separation is one of the most successful patterns in software engineering. There are many reasons why it is good, but here's two:
  • you may have more than one view for the same data model
  • view objects hold state related to retained mode graphics, which models do not need, allowing them to be simpler.
Having said all of that, you certainly could store your models in HTML DOM (or XML). But even if your model was in (X)HTML, I don't think ShadowDOM and <content select>, as currently designed, are the right tools to integrate it into the custom elements.


Seth Ladd

unread,
Sep 18, 2013, 8:09:19 PM9/18/13
to John Messerly, ed eustace, polymer-dev
I can use an observer to listen when children <todo-item> elements are added or removed. And then update my data model.
 
  • Is it possible to fetch the data from the server and/or local storage?
Assuming I have bindings between child DOM nodes and my data model, I'm hoping data persistence just kinda works. 
  • How does the memory cost and access time of data-in-DOM compare to data-in-JavaScript-heap?
I'm assuming/hoping that there's data binding between child nodes in light dom and my data-in-JavaScript. This can be kept in sync much like how template bindings keep things in sync today.

If I am understanding, it sounds like you still want your data in JavaScript objects, but you also want it to be two way mirrored in the DOM tree. Does that sound right? What purpose does that serve? Is the idea to use HTML as a serialization language? It seems to

The purpose for a DOM "API" is to embrace the DOM as a location of the semantic structure, and help continue to make the web crawlable and discoverable. I could be wrong, but if my page is simply <my-app></my-app>, with all my info in models and shadow dom, a web crawler can't find anything useful in my page.

(unless a crawler can look into shadow dom?)

John Messerly

unread,
Sep 18, 2013, 8:38:00 PM9/18/13
to Seth Ladd, ed eustace, polymer-dev
Aha, a wild web crawler appears! Let's unpack this topic a bit. I hope you will see it is unrelated to our previous model-in-DOM discussion :)

Crawlers want to learn information about websites so they can find useful search results for ugly-bags-of-mostly-water (that's us humans). As such, they need to see the page's semantic structure as it is presented to a human. In other words, they're about finding content, not data. (if we're talking about a data search engine, this might be a different story). So our friendly neighborhood web crawler is going to want to see those <a> tags most of all.

Let us assume our little web crawler is using an HTML parser, but has no way of running script code. It parses HTML into an AST. This AST may in fact be similar to a browser's DOM, but it's the crawler using the AST, not script. Here, you can see that the notion of Shadow DOM has no meaning to our crawler. There was no code executed, so no shadow DOM exists. The crawler's DOM probably would not bother implementing Shadow DOM unless it wanted to run script code. But if it did implement shadow DOM, it most definitely can see inside. Think of it this way: imagine you write a script to parse some code with Python's lovely html5lib. Let's say html5lib can run JS and has ShadowDOM. Do you think shadow DOM can prevent your Python script code from traversing inside its own AST? Of course not. Your code owns that in-Python DOM and everything in Python's heap. You can do whatever you want. :)

Now, let's instead go back to the case of a naive crawler, ignorant of the ways of the brave-new-web-component-world. Did our server serve a page with <link rel=import> and/or custom-elements to the crawler? If it did, there's no way a legacy crawler will make sense of it! It has nothing to do with Shadow DOM, it's just the fault of custom elements. If the crawler thinks <todo-app> is an HTMLUnknownElement, it's not going to find the associated <polymer-element> or have any idea of what the <template> inside means, and it certainly isn't going to make a Shadow DOM (remember, only script execution can create a shadow dom). Poor crawler!

I'll leave the best way to deal with this smarter folks than me :). My 2 cents -- the burden is on your web server to serve a page that the user-agent understands. If you see an old crawler, give it something that doesn't use custom elements. Hopefully, the set of crawlers is small enough that they'll be updated to understand the modern "living standard" that we call HTML, and they'll have some way of understanding these modern pages. The folks writing crawlers are pretty sharp, I think they will find a way. I do worry a bit about the demise of <element>, but that's another topic.

Seth Ladd

unread,
Sep 18, 2013, 8:52:29 PM9/18/13
to John Messerly, ed eustace, polymer-dev
Thanks John. I was curious and looked at the source of polymer-project.org. I see this:

<docs-menu>
  <polymer-ui-menu>
    <polymer-ui-submenu-item>
    <polymer-ui-submenu-item>
    <polymer-ui-submenu-item>

...In the light DOM. That looks awesome to me, and I'm very glad not to see <homepage-docs-menu></homepage-docs-menu> :)

I think we need to show more examples of custom elements with light dom + semantic nesting of tags. If a web crawler sees:

<todo-app>
  <todo-item>Learn Polymer</todo-item>
</todo-app>

, surely that must be better than <todo-app></todo-app> ? At least it can find some text in the former example.

John Messerly

unread,
Sep 18, 2013, 9:29:00 PM9/18/13
to Seth Ladd, ed eustace, polymer-dev
Yeah. If you can get the <a>'s in there, like polymer's homepage does, it's good. I see how it works for static content, but not how it works for per-user dynamic data like TODOs or mail items. I doubt our crawler is going to be adding todo's for itself, at least not for a few more years :).

Eric Bidelman

unread,
Sep 18, 2013, 10:26:54 PM9/18/13
to Seth Ladd, John Messerly, ed eustace, polymer-dev
The difference between <todo-app> and <polymer-ui-menu> is that the first is
a dynamic app and the second is static markup. When things become dynamic we're talking the composed tree. Does it matter where things live (shadow vs light) at that point? A crawler needs to understand something about live dom, not static markup.

<todo-app> produces markup from a data model. DOM is the "rendered view" of that model. You could architect the element Seth's way, but it feels backwards to me. The model should be in the driver's seat. Things also get more challenging (you'd need mutation observers to monitor light dom children, there's no source of truth for the data, styling becomes more difficult with distributed nodes). It would be too complex as our hello world app.

On the other hand, an element like <polymer-ui-menu> isn't driven by a model. It's job is to render user-supplied markup in a specific way.

Seth, I think there's a place for both types of examples. Polymer should probably make working with light dom easier, but architecture depends on use case. The main reason we keep things in a <polymer-element> is to demonstrate proper use of data binding. Writing less code feels good when you're learning a bunch of new concepts  \m/

-Eric

....fun fact: at one point we had 4-5 different versions of todomvc. The current one is what we settled on as the "polymeric way". Nothing is set in stone.







Dimitri Glazkov

unread,
Sep 19, 2013, 11:40:32 AM9/19/13
to Eric Bidelman, Seth Ladd, John Messerly, ed eustace, polymer-dev
FWIW, I can't wait for someone to come up with a Web Components-based
opinionated framework that takes a document-as-a-model point of view,
rather than document-as-a-view, like Polymer does. Then we could race
and compare results :)

:DG<

Scott Miles

unread,
Sep 19, 2013, 1:16:24 PM9/19/13
to Dimitri Glazkov, Eric Bidelman, Seth Ladd, John Messerly, ed eustace, polymer-dev
Er, I don't think it's correct to say Polymer takes a 'document-as-view' approach. When we say 'everything is an element', we really mean we use them for everything: data, view, agents, and api. 

There are several places we have used document-as-model, I guess these are not as easy to stumble into as some of the other versions. As time goes on we will have better organized examples, so I can be less hand-wavy. 

Also, fwiw, if you look at TodoMVC the model and data marshaling is peer to the <td-todos> ... it's not a one element app. The todos themselves are not sitting there because there aren't any at startup. The data comes out of local storage, which drives the design of the data marshaling for this app.

S

Scott Miles

unread,
Sep 19, 2013, 1:17:49 PM9/19/13
to Dimitri Glazkov, Eric Bidelman, Seth Ladd, John Messerly, ed eustace, polymer-dev
I wrote <td-todos> where I meant <td-app>. Also, fwiw, the name <td-app> is a mistake IMO. Components are reusable, it's not an 'app' it's just a high level view.

ed eustace

unread,
Sep 19, 2013, 1:33:57 PM9/19/13
to Scott Miles, Dimitri Glazkov, Eric Bidelman, Seth Ladd, John Messerly, polymer-dev
Would be interested to see some document as data samples, mainly to look at how the binding can/should be set up. Doing that with mdv is pretty straightforward (hooray). 
I'm still mid-grok here so thanks for the info so far.
Ed

Reply all
Reply to author
Forward
0 new messages