点亮的 Web 组件未更新 Polymer 元素属性

Lit web component not updating Polymer element attribute

提问人:devjklein 提问时间:9/8/2022 最后编辑:connexodevjklein 更新时间:9/14/2022 访问量:88

问:

我一直在引用 Home Assistant 项目在 Lit 库中使用 Polymer 应用程序布局元素。我遇到的问题是我无法在自定义组件中获取公共属性来更新嵌套 Polymer 元素上的属性。

这是我目前的代码:

import { LitElement, html, css, PropertyValues } from 'lit';
import { customElement, state, query, property } from 'lit/decorators.js';

import "@polymer/app-layout/app-drawer-layout/app-drawer-layout";
import type { AppDrawerLayoutElement } from "@polymer/app-layout/app-drawer-layout/app-drawer-layout";
import "@polymer/app-layout/app-drawer/app-drawer";
import type { AppDrawerElement } from "@polymer/app-layout/app-drawer/app-drawer";

import { listenMediaQuery } from "./common/media-query";
import { toggleAttribute } from "./common/toggle-attribute";


declare global {
    // for fire event
    interface WSDomEvents {
        "ab-toggle-menu": undefined;
    }
}

@customElement('ab-app')
class WsApp extends LitElement {
    static styles = css`
        :host {
            --app-drawer-width: 56px;
        }
        :host([expanded]) {
            --app-drawer-width: 256px;
        }

        button {
            width: 100%;
            height: 56px;
            border: 0;
            background-color: var(--color-accent);
            color: #FFF;
            display: flex;
            align-items: center;
            font-size: var(--font-size-large);
        }

        svg {
            padding: 8px;
            height: 100%;
            width: auto;
        }

        .label {
            display: none;
            padding: 10px;
        }

        :host([expanded]) .label {
            display: inline;
        }

        .ab-sidebar {
            background-color: var(--color-accent)!important;
            height: 100%;
        }
    `;

    @property({ type: Boolean, reflect: true }) public narrow!: boolean;
    @property({ type: Boolean }) public alwaysExpand = false;

    constructor() {
        super();
        listenMediaQuery("(max-width: 870px)", (matches) => {
            this.narrow = matches;
        });
    }

    protected render() {
        const sidebarNarrow = this._sidebarNarrow
        return html`
            <app-drawer-layout
                responsiveWidth="870px"
            >
                <app-drawer
                    class="app-drawer"
                    swipe-open
                    slot="drawer"
                    align="left"
                    ?persistent=${!this.narrow}
                >
                    <div class="ab-sidebar">
                        <button @click=${this.toggleSidebar}>
                            <svg style="width:24px;height:24px" viewBox="0 0 24 24">
                                <path fill="currentColor" d="M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z" />
                            </svg>
                            <span class="label">Collapse Menu</span>
                        </button>
                        <button @click=${this.toggleSidebar}>
                            <svg style="width:24px;height:24px" viewBox="0 0 24 24">
                                <path fill="currentColor" d="M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z" />
                            </svg>
                            <span class="label">Home</span>
                        </button>
                        <button @click=${this.toggleSidebar}>
                            <svg style="width:24px;height:24px" viewBox="0 0 24 24">
                                <path fill="currentColor" d="M12,3C10.73,3 9.6,3.8 9.18,5H3V7H4.95L2,14C1.53,16 3,17 5.5,17C8,17 9.56,16 9,14L6.05,7H9.17C9.5,7.85 10.15,8.5 11,8.83V20H2V22H22V20H13V8.82C13.85,8.5 14.5,7.85 14.82,7H17.95L15,14C14.53,16 16,17 18.5,17C21,17 22.56,16 22,14L19.05,7H21V5H14.83C14.4,3.8 13.27,3 12,3M12,5A1,1 0 0,1 13,6A1,1 0 0,1 12,7A1,1 0 0,1 11,6A1,1 0 0,1 12,5M5.5,10.25L7,14H4L5.5,10.25M18.5,10.25L20,14H17L18.5,10.25Z" />
                            </svg>
                            <span class="label">Weighing</span>
                        </button>
                        <button @click=${this.toggleSidebar}>
                            <svg style="width:24px;height:24px" viewBox="0 0 24 24">
                                <path fill="currentColor" d="M17 5H20L18.5 7L17 5M3 2H21C22.11 2 23 2.9 23 4V8C23 9.11 22.11 10 21 10H16V20C16 21.11 15.11 22 14 22H3C1.9 22 1 21.11 1 20V4C1 2.9 1.9 2 3 2M3 4V8H14V4H3M21 8V4H16V8H21M3 20H14V10H3V20M5 12H12V14H5V12M5 16H12V18H5V16Z" />
                            </svg>
                            <span class="label">Edit</span>
                        </button>
                    </div>
                </app-drawer>
                <slot name="app"></slot>
            </app-drawer-layout>
        `;
    }

    protected firstUpdated() {
        this.addEventListener("ab-toggle-menu", () => {
            if (this._sidebarNarrow) {
                if (this.drawer.opened) {
                    this.drawer.close();
                } else {
                    this.drawer.open();
                }
            } else {
                setTimeout(() => this.appLayout.resetLayout());
            }
        });
    }

    protected updated(changedProps: PropertyValues) {
        if (changedProps.has("alwaysExpand")) {
            toggleAttribute(this, "expanded", this.alwaysExpand);
        }
    }

    private _toggleSidebar(ev: CustomEvent) {
        if (ev.detail.action !== "tap") {
            return;
        }
        this.dispatchEvent(new CustomEvent('ab-toggle-menu'));
    }

    private toggleSidebar() {
        this.toggleAttribute("expanded");
        //this.requestUpdate;
    }





    private get _sidebarNarrow() {
        return this.narrow;
    }

    private get drawer(): AppDrawerElement {
        return this.shadowRoot!.querySelector("app-drawer")!;
    }

    private get appLayout(): AppDrawerLayoutElement {
        return this.shadowRoot!.querySelector("app-drawer-layout")!;
    }
}

我正在苦苦挣扎的是在我的 render() 下。聚合物元素应用程序抽屉具有属性“persistent”,但是将其设置为我的“narrow”属性(由媒体查询驱动)不会在站点上添加或删除“persistent”属性。“persistent”属性仍以 640px(默认值)切换。?persistent=${!this.narrow}

responsiveWidth="870px"在 app-drawer-layout 上也不做任何事情。

为什么这不起作用?我遵循了 Lit 的聚合物用户指南中关于布尔属性的建议。它显然适用于家庭助理项目,但我不知道我错过了哪些部分。

TypeScript 聚合物 Web 组件 lit-element lit

评论


答:

0赞 connexo 9/14/2022 #1

使用该属性而不是属性,方法是在属性前面加上以下前缀:.

   .persistent=${!this.narrow}