AlbertL
AlbertL

Reputation: 41

How to do data binding in polymer with meteor

I'm very new to data binding and the two frameworks. Right now I'm pretty stuck at how to bind the data within a polymer element.

For example, I have a book list with books' name. If I only use blaze to do the rendering, I would do it in the follow way:

//app.js
Template.bookList.helpers({
  books: function () {
    return Books.find({});
  }
});

//app.html
<template name="bookList">
   <h1>List</h1>
   <ul>
   {{#each books}}
    {{> book}}
   {{/each}}
   </ul>
</template>

<template name="book">
  <li>{{name}}</li>
</template>

Now I'm using it with polymer, I do:

//my-book-list.html
<polymer-element name="my-book-list">
  <template>
     <h1>List</h1>
     <content></content>
  </template>
</polymer-element>

//app.html
<template name="bookList">
   <my-book-list>
      <ul>
      {{#each books}}
        {{> book}}
      {{/each}}
      </ul>
   </my-book-list>
</template>

<template name="book">
  <li>{{name}}</li>
</template>

So I place the dynamic data inside of the polymer item through the content block. Although it still does the job, I don't want it that way. I want to do the data-binding inside the polymer element, something like(I hope it makes sense to you):

//my-book-list.html
<polymer-element name="my-book-list">
  <template bind="{{books}}">
     <h1>List</h1>
     <ul>
       <template repeat>
         <li>{{name}}</li>
       </template>
     </ul>
  </template>
</polymer-element>

//app.html
<template name="bookList">
   <my-book-list></my-book-list>
</template>

Is there a way to do it? Thanks in advance.

Progress:

I now can put books purely inside the polymer element, the problem now is that it doesn't seem to react when the data change because polymer doesn't observe change of a object, and I am struggling in finding a way to observe all the nested values inside a object:

<polymer-element name="my-book-list">
  <template bind="{{books | mapBooks}}">
     <h1>List</h1>
     <ul>
       <template repeat>
         <li>{{name}}</li>
       </template>
     </ul>
  </template>
  <script>
    Polymer("my-book-list", {
      books: Books.find(),
      mapBooks : function(booksCursor) {
        return booksCursor.map(function(p) { return {id: p.id, name: p.name}})
      }
    });
  </script>
</polymer-element>

Upvotes: 2

Views: 624

Answers (1)

AlbertL
AlbertL

Reputation: 41

Finally got a hacky solution, but I don't know if this is the best practice or not:

<polymer-element name="my-book-list">
  //Force polymer to update DOM when books.lastUpdate change
  <template bind="{{books.lastUpdate | getBooks}}"> 
     <h1>List</h1>
     <ul>
       <template repeat>
         <li>{{name}}</li>
       </template>
     </ul>
  </template>
  <script>
    Polymer("my-book-list", {
      ready: function() {
        var books = this.books;
        this.books.observeChanges(  //Observe the change of cursor and update a field
        {
          added: function(id, fields) {
            console.log("Item added");
            books.lastUpdate = new Date();
          },
          changed: function(id, fields) {
            console.log("Item changed");
            books.lastUpdate = new Date();
          },
          removed: function(id, fields) {
            console.log("Item deleted");
            books.lastUpdate = new Date();
          }
        }
      ),
      books: Books.find(),
      getBooks : function() {
        return Books.find().map(function(p) { return {id: p.id, name: p.name}})
      }
    });
  </script>
</polymer-element>

Upvotes: 2

Related Questions