Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unclear how to bind complex data objects to new instances of polymer-element as a passed-in attribute #488

Closed
lozandier opened this issue May 2, 2014 · 9 comments

Comments

@lozandier
Copy link

The Problem

There seems to be an issue binding complex objects w/ Polymer than what I'm familar with. I'm using the latest version of polymer, as well as platform.js.

What I mean by 'complex objects'

I'm familiar creating web components natively that can bind to complex objects as the model it supports as shown below:

index.html

<template bind={{ supermodel }}>
  <div> {{supermodel.name}}</div> 
</template> 

main.coffee

template = document.querySelector('template'); 

# Check if the template element is properly supported in the current browser enviroment I'm currently developing this element on
if 'content' in  template 
  template.model = {
    supermodel: 
      name: "Kate Upton" 
  }
  # For Non-Chrome Browsers 
  Platform.performMicrotaskCheckPoint() 

else 
  console.log "Basic <template></template> support is failing, I have to replace this with a proper fallback. "

*Of course, this is not enough since I would have create a prototype for the new element that inherits from HTMLElementPrototype and document.register to register the x-supermodel element as a valid element instead of HTMLUnknownElement *

Detailed explanation of the problem

With the latest version of Polymer, creating elements for basic types is straightforward as always:

index.haml

%polymer-element{ name: "x-supermodel", attributes: "name"} 
  %template 
    %span {{ name  }}
  %script{src: "scripts/elements/supermodel_basic.js"}

%x-supermodel{name: "Kate Upton"} 

supermodel_basic.coffee (works)

Polymer('x-supermodel', name: "Unnamed Model")

However, the following should work, but doesn't when attempting to bind a complex object:

index.haml

%polymer-element{ name: "x-supermodel", attributes: "name supermodel"} 
  %template   
    %span {{ supermodel.name  }}
  %script{src: "scripts/elements/supermodel.js"}

%x-supermodel{name: "Kate Upton"} 

supermodel.coffee (doesn't work)

Polymer 'x-supermodel', { 
  created: ->
    @supermodel = { name: "Unnamed Model" }
}

According to Chris Buckett (author of Web Components in Action), this pattern should work to bind a complex object & instances of polymer-element together. Did the latest version(s) of Polymer change the way complex objects can be binded as a model?

@sjmiles
Copy link
Contributor

sjmiles commented May 2, 2014

I can't figure out what your example is doing because you transformed the syntax using CoffeeScript and whatever 'haml' is. Posting a JSBin using canonical syntax will get you a much more effective response.

Here is an example: http://jsbin.com/xumiqolu/3/edit

@lozandier
Copy link
Author

Okay, I've created a pen that allows you to view the code as plain 'ol .html and js by pressing the eye icon on the appropriate panel: http://codepen.io/lozandier/pen/GKbFm

@lozandier lozandier changed the title Complex data types not working as expected Unclear how to bind complex data objects to new instances of polymer-element May 2, 2014
@sjmiles
Copy link
Contributor

sjmiles commented May 2, 2014

Actual running examples are superior, afaict, you are just sending source.

In any case, name and supermodel.name are completely different pieces of data. You are setting name to a value and then expecting it to appear in supermodel.name.

@lozandier
Copy link
Author

I should have done the following instead instead?

this.supermodel =  {
  name: this.name
}

That's what I thought until "Unnamed Model" didn't pop up as well if I'm interpreting your comment correctly...

My this.name isn't going nowhere intentionally since a seemingly direct call to supermodel.name(via "Unnamed Model") isn't working either...

@sjmiles
Copy link
Contributor

sjmiles commented May 2, 2014

There is some basic misunderstanding, but I cannot tell what it is you are trying to achieve. My first JSBin was not helpful?

Here is another try: http://jsbin.com/xumiqolu/3/edit

It's much easier to discuss in terms of a working example.

@lozandier lozandier changed the title Unclear how to bind complex data objects to new instances of polymer-element Unclear how to bind complex data objects to new instances of polymer-element as a passed-in attribute May 2, 2014
@lozandier
Copy link
Author

Your example definitely clears things up a bit except the attributes part that has me a bit stumped.

I'm trying to be able to set the name by setting it through an attribute

<x-supermodel name="Kate Upton"></x-supermodel> 

Another element (beer-item) was supposed to demonstrate this what I'm trying to accomplish is the following code below, but it doesn't work (from Web Components in Action):

index.html

<polymer-element name="beer-item"                         
       attributes="beerName imageUrl pints beer">            
     <template>
       <div class="beer">                                   
         <img src="{{beer.imageUrl}}">                       
         <span>{{beer.beerName}}</span>                    
         <div>{{beer.pints}} pints tasted so far</div>      
       </div>
     </template>
    <script src="beer_item.js>
</polymer-element> 

beer_item.js

var beerApp = beerApp || {};
beerApp.BeerItem = function(beerName, imageUrl, pints) {
     this.beerName = beerName || '';
     this.imageUrl =  imageUrl || 'beer.png';
    this.pints = pints || 0;
   };

Polymer('beer-item', {
     created: function() {
       this.beer = new BeerItem(this.beerName || '',   
                                this.imageUrl || '',   
                                this.pints || 0);       
} });

@sjmiles
Copy link
Contributor

sjmiles commented May 2, 2014

The attributes map directly to properties. You can set supermodel via an attribute, you can set name via an attribute, but you cannot set supermodel.name via an attribute.

Here are some more examples:
http://jsbin.com/xumiqolu/4/edit

All the attributes are distinct, there is no automatic mapping of beerName to beer.beerName, it's possible your reference material is in error.

@lozandier
Copy link
Author

Understood, it's now a whole lot clear to me now to accomplish what I wanted from polymer-elements as far as supporting complex objects.

I can't thank you enough for the detailed examples (especially considering the fact it's Friday).

The reference material I've provided must be using an older version of Polymer or something then. I'll immediately notify the author.

@sjmiles
Copy link
Contributor

sjmiles commented May 2, 2014

Great, that's what we're here for. Don't hesitate to post more questions.

@sjmiles sjmiles closed this as completed May 2, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants