Custodian
Custodian

Reputation: 21

How to set property value in Polymer 2.x?

I'm stuck with one simple problem in Polymer 2.x. I don't know how to set correctly a value of my custom element properties from another elements class.

My code:

<dom-module id="cookbook-wall">
<template>
    <style>
        // my styling
    </style>

    <div class="wall">
        <template is="dom-repeat" items="[[_getRecipesList()]]">
            <cookbook-recipe-card name="recipe-card"></cookbook-recipe-card>
        </template>
    </div>
</template>

<script>
    class CookbookWall extends Polymer.Element {
        static get is() {
            return 'cookbook-wall';
        }

        static get properties() {

        // this property is unused now, I tried to set it dynamically from 
        // method below but it also failed
            return {
                recipes: Array
            }
        }

        _getRecipesList() {
            var test = new CookbookRecipeCard();
            test.setData("This is test title", "This is test content");

            return [test, test, test];
        }
    }

    window.customElements.define(CookbookWall.is, CookbookWall);
</script>

and

<dom-module id="cookbook-recipe-card">
<template>
    <style include="shared-styles">
       // my styling
    </style>

    <div class="card">
        <div id="titleContent">{{title}}</div>

        <div class="my-block">
            <div class="contentCaption">Treść przepisu:</div>
            <div class="content">{{content}}</div>
        </div>
    </div>
</template>

<script>
    class CookbookRecipeCard extends Polymer.Element {
        static get is() {
            return 'cookbook-recipe-card';
        }

        static get properties() {
            return {
                myName: String,
                myContent: String
            }
        }

        setData(myTitle, myContent) {
            this.myTitle = myTitle;
            this.myContent = myContent;
        }

    }

    window.customElements.define(CookbookRecipeCard.is, CookbookRecipeCard);
</script>

As can u see I want do do sth like: setData(myTitle, myContent) from another elements class, but it doesn't work. Is there any way to achieve similar result as with traditional setter in object-oriented languages in Polymer?

Thanks for any help!

EDIT (My solution):

I deleted my custom card component and just used normal paper-card:

<dom-module id="cookbook-wall">
<template>
    <style>...</style>

    <div class="wall">
        <template id="cardSet" is="dom-repeat" items="[[_getArray()]]" as="card">
            <paper-card id="myCard">
                <div class="card">
                    <div id="titleContent">[[card.title]]</div>

                    <div class="my-block">
                        <div class="contentCaption">Treść przepisu:</div>
                        <div class="content">[[card.text]]</div>
                    </div>
                </div>
            </paper-card>
        </template>
    </div>
</template>

<script>
    class CookbookWall extends Polymer.Element {
        static get is() {
            return 'cookbook-wall';
        }

        _getArray() {
            // example usage
            return [{'title': 'Title 1', 'text': 'Description 1'},
                {'title': 'Title 2', 'text': 'Description 2'},
                {'title': 'Title 3', 'text': 'Description 3'}];
        }
    }

    window.customElements.define(CookbookWall.is, CookbookWall);
</script>

Upvotes: 0

Views: 963

Answers (2)

Tanin
Tanin

Reputation: 1933

Here's one design that might be better. It allows a user of cookbook-wall to set cards, while supplying the default value of cards.

<dom-module id="cookbook-wall">
<template>
    <style>...</style>

    <div class="wall">
        <template id="cardSet" is="dom-repeat" items="[[cards]]" as="card">
            <paper-card id="myCard">
                <div class="card">
                    <div id="titleContent">[[card.title]]</div>

                    <div class="my-block">
                        <div class="contentCaption">Treść przepisu:</div>
                        <div class="content">[[card.text]]</div>
                    </div>
                </div>
            </paper-card>
        </template>
    </div>
</template>

<script>
    class CookbookWall extends Polymer.Element {
        static get is() {
            return 'cookbook-wall';
        }

        static get properties() {
          return {
            cards: {
              type: Array,
              value: () => {
                return [
                  {'title': 'Title 1', 'text': 'Description 1'},
                  {'title': 'Title 2', 'text': 'Description 2'},
                  {'title': 'Title 3', 'text': 'Description 3'}];
              }
          };
        }
    }

    window.customElements.define(CookbookWall.is, CookbookWall);
</script>

Upvotes: 0

Benny Powers
Benny Powers

Reputation: 5836

These are just regular JavaScript/DOM properties, so you can set them in js with elements.recipeList = [item, item, item]; then in your template, the dom repeater might look something like

   <template is="dom-repeat" items="[[recipeList]]">
        <cookbook-recipe-card name="recipe-card" recipe="[[item]]"></cookbook-recipe-card>
    </template>

Notice how in this example I'm passing the item as recipe property to the card via the recipe attribute.

You could also compute the recipeList property by defining it in your host element as so

   static get properties() {
        return {
            recipeList: {
              type: Array,
              computed: "_getRecipeList(dependencies)"
        }
    }

The advantage to computed properties is that they're readable from outside the element.

Upvotes: 1

Related Questions