如何重新呈现Web组件的单个元素?

时间:2019-05-08 09:12:35

标签: javascript html web-component

我正在创建一个Web组件,我想显示选定的项目。 有一个父组件,它从api获取数据并创建一个填充有该数据的组件。这是一个非常精简的版本,但是您应该会遇到问题。

父组件看起来像

const myComponent = document.createElement('template');

class MyComponent extends HTMLElement {
    render(el) {
        if (this.selectedItems.length === 0) {
            selectedContent = `Nothing selected!`;
        } else {
            selectedContent = `<p>Selected:</p>`;
            selectedContent += `<ul>`;
            for (let item of this.selectedItems) {
                selectedContent += `<li>${item.name}</li>`;
            }
            selectedContent += `</ul>`;
        }

        el.shadowRoot.innerHTML = `
            <div>
                <child-component data="${el._data}"></child-component>
                ${selectedContent}
            </div>`;
    }

    constructor() {
        super();

        let self = this;

        self.myService= new MyService();
        self.myItemsList= [];
        self.selectedItems = [];
        self.attachShadow({mode: 'open'});

        self.fetchData(self);
        self.setupEventListeners(self);
    }

    async fetchData(self) {
        try {
            const response = await self.myService.getData();
            const items = response.data;
            items.forEach((item) => {
                self.myItemsList.push({item});
            });
            self.render(self);
        } catch (error) {
            console.log(error);
        }
    }

    setupEventListeners(self) {
        EventBus.addEventListener("my-custom-event", (event) => {
            const item = event.target;
            if (item.active === true) {
                    self.selectedItems = _.reject(self.selectedItems, (element) => {
                        return element.name === self.myItemsList[item.position].name;
                    });
                    self.myItemsList[item.position].checked = false;
            } else if (item.active === false) {
                    self.selectedItems.push(item);
                    self.myItemsList[item.position].checked = true;
            } 
            self.render(self);
        });
    }

    attributeChangedCallback(attrName, oldVal, newVal) {
        if (oldVal !== newVal) {
            this[`_${attrName}`] = newVal;
            this.render(this);
        }
    }

    connectedCallback() {
        this.render(this);
        this.appendChild(myComponent.content.cloneNode(true));
    }
}

window.customElements.define("bootstrap-card-parent", BootstrapCardParent);

子组件:

const myComponentChild = document.createElement('template');


class MyChildComponent extends HTMLElement {
    render(el) {
        el.shadowRoot.innerHTML = `
            <div>${el._data}</div>
            <input type="checkbox"
onchange="MyChildComponent.onAddToSelectedRequest(${el._data})">`;
    }

    static get observedAttributes() {
        return ['data'];
    }

    constructor() {
        super();
        this.attachShadow({mode: 'open'});
    }

    attributeChangedCallback(attrName, oldVal, newVal) {
        if (oldVal !== newVal) {
            this[`_${attrName}`] = newVal;
            this.render(this);
        }
    }

    connectedCallback() {
        this.render(this);
        this.appendChild(myComponentChild.content.cloneNode(true));
    }

    static onAddToSelectedRequest(someData) {
        EventBus.dispatch("my-custom-event", someData);
    }
}

window.customElements.define("my-child-component", MyChildComponent);

当前,我在EventListener中调用self.render(self)以重新渲染页面以查看我的数据。没有办法只重新渲染所选项数组的内容吗?

0 个答案:

没有答案