Databind iron-ajax JSON response entry to nested P

2019-07-25 23:55发布

问题:

I've got a Polymer app running an iron-ajax call to a service that returns a json string:

{
    "name": "John"
}

The Polymer code on the main page is:

<link rel="import" href="/elements/my-form.html">

<dom-module id="my-app">

    <template>

        ...

        <iron-ajax auto url="/grabData" handle-as="json" last-response="{{data}}"></iron-ajax>

        <iron-label>
            From iron-ajax = {{data.name}}
        </iron-label>

        <my-form></my-form>

       ...

"my-form" is:

<link rel="import" href="/my-name.html">

<dom-module id="my-form">

    <template>
        <my-name></my-name>
    </template>

    <script>
        Polymer({
            is: 'my-form'
        });
    </script>

</dom-module>

And "my-name" is:

<dom-module id="my-name">

    <template>
        <iron-label>
            From my-name = {{data.name}}
        </iron-label>
    </template>

    <script>
        Polymer({
            is: 'my-name'
        });
    </script>

</dom-module>

When run, "From iron-ajax = John", and "From my-name =".

While I could use a single ajax call within my-name, I'd don't want to do this for every custom element. I'd rather acquire my data in one call and have custom elements access the returned data.

How do I acquire 'name' within my-name without passing the value through the my-form element?

--- Update ---

For a little more clarity on desired outcomes, here's a little more info.

Ultimately I'd like to acquire a very large JSON string with multiple entries:

{
    "name": "John",
    "address": [{
        "street" : "14 Baker Street",
        "city" : "somewhereville"
    }],
    "phone": "123-1234"
    ...
}

And have custom elements handle each entry:

<dom-module id="my-form">

    <template>
        <my-name></my-name>
        <my-address></my-address>
        <my-phone></my-phone>
        ...
    </template>

回答1:

Below is the example snippet on how to pass data between elements. Instead of ajax call i've passed data from element's attribute. Some key points to be noted

  • In case you want to pass whole data to child elements you can replace name property in child element with data property of parent, names doesn't have to be same, eg if child has a property user with type Object(first letter caps) then your binding will be user={{data}}
  • If you want you can replace {{}} with [[]], unless you want to propagate change from child to parent in which case you will have to add another parameter to name property namely notify and set its value as true, something like

    name:{
     type:String,
     notify:true
    }
    
  • In your case(with ajax call) listing name and data inside properties is optional, but i'll recommend it as it makes it easy to add new features to a property(like notify) and also makes it easy to track all the properties in a large element.

  • For more details on properties and data-binding checkout these links. properties, data-binding

<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">


<dom-module id="my-app">
  <template>
    Name from App: {{data.name}}
    <br>
    <my-form name={{data.name}}></my-form>
  </template>
</dom-module>
<script>
  Polymer({
    is: 'my-app',
    properties: {
      data: {
        type: Object
      }
    }
  });
</script>



<dom-module id="my-form">
  <template>
    Name from Form: {{name}}
    <br>
    <my-name name={{name}}></my-name>
  </template>
</dom-module>
<script>
  Polymer({
    is: 'my-form',
    properties: {
      name: {
        type: String
      }
    }
  });
</script>

<dom-module id="my-name">
  <template>
    Name from Name: {{name}}
  </template>
</dom-module>
<script>
  Polymer({
    is: 'my-name',
    properties: {
      name: {
        type: String
      }
    }
  });
</script>


<my-app data='{"name":"User1"}'></my-app>