मेरे पास एक लिटलेमेंट आधारित वेब घटक है, जो एक कस्टम तत्व के साथ एक एमडीडब्ल्यू-संवाद प्रस्तुत करता है जो मूल घटक से संपत्ति का उपयोग करता है। जब उपयोगकर्ता एक बटन पर क्लिक करता है, तो संवाद दिखाया जाता है जो कुछ इनपुट फ़ील्ड प्रस्तुत करता है। यह सब बहुत अच्छा काम करता है, लेकिन मैं चाहता हूं कि जब भी बटन क्लिक किया जाए, संवाद दिखाए जाने से पहले संपत्ति को खाली ऑब्जेक्ट पर रीसेट कर दिया जाए और हालांकि मैं आसानी से ऐसा कर सकता हूं - ऐसा लगता है कि संवाद तत्वों पर इसका कोई प्रभाव नहीं पड़ता है।

मूल तत्व

export class PageApplications extends LitElement {

    static get properties() {
        return {
            application: { type: Object }
        }
    }

    constructor() {
        super();
        this.application = {};
    }

    onMouseOver(event) {
        this.shadowRoot.querySelector('mwc-fab').extended = ('mouseenter' === event.type);
    }

    openDialog() {
        console.log('PageApplication.openDialog:', this.application);
        this.application = {};
        let dialog = this.shadowRoot.querySelector('mwc-dialog');
        dialog.requestUpdate;
        dialog.open = true;
    }

    closedDialog(event) {
        console.log('closedDialog:', this.application)
        if ('ok' === event.detail.action) {
            // NOP
        }
    }

    render() {
        console.log('PageApplication.render', this.application);
        return html`
            <style type="text/css">
                mwc-fab {
                    position: fixed;
                    right: 1rem;
                }
                mwc-list {
                    background-color: #FFF;
                }
            </style>
            <mwc-fab showIconAtEnd icon="add_circle" label="New Application" 
                @mouseenter="${this.onMouseOver}"
                @mouseout="${this.onMouseOver}"
                @click="${this.openDialog}"
                >
            </mwc-fab>
            <mwc-dialog heading="Create Application"
                @closed="${this.closedDialog}">
                <cnvy-create-application
                    .application="${this.application}"
                ></cnvy-create-application>
                <mwc-button
                    slot="primaryAction"
                    dialogAction="ok"
                >Create</mwc-button>
                <mwc-button
                    slot="secondaryAction"
                    dialogAction="cancel"
                >Cancel</mwc-button>            
            </mwc-dialog>
            <h2>Applications</h2>

जैसा कि आप देख सकते हैं कि एप्लिकेशन गुण तत्व cnvy-create-application के लिए बाध्य है

export class ConvoyCreateApplication extends LitElement {

    constructor() {
        super();
    }

    static get properties() {
        return {
            application: { type: Object }
        }
    }

    render() {
        console.log('ConvoyCreateApplication.render', this.application);
        return html`
            <style>
                mwc-formfield {
                    display: block;
                }
            </style>
            <mwc-formfield>
                <mwc-textfield 
                    placeholder="Name" 
                    helper="Name of application"
                    .value="${this.application.name}"
                    @change="${e => this.application.name = e.target.value}"
                    ></mwc-textfield>
            </mwc-formfield>
            <mwc-formfield>
                <mwc-textarea 
                    rows="2" 
                    placeholder="Description" 
                    helper="Short description"
                    .value="${this.application.description}"
                    @change="${e => this.application.description = e.target.value}"
                ></mwc-textfield>
            </mwc-formfield>
        `;
    }

}
customElements.define('cnvy-create-application', ConvoyCreateApplication);

समस्या यह है - पहली बार जब मैं बटन पर क्लिक करता हूं, तो संवाद अपेक्षित के रूप में दिखाया जाता है और प्रत्येक टेक्स्टफील्ड "अपरिभाषित" कहता है, जो शायद ठीक है क्योंकि प्रोप खाली वस्तु में परिभाषित नहीं हैं। मैं क्रमशः "ए" और "बी" मान दर्ज करता हूं और संवाद और कंसोल प्रिंट में ठीक क्लिक करता हूं

closedDialog: {name: "a", description: "b"}

जैसा सोचा था। यदि मैं फिर से बटन पर क्लिक करता हूं, तो "एप्लिकेशन" संपत्ति को खाली वस्तु पर रीसेट किया जाना चाहिए, लेकिन यूआई "ए" और "बी" के साथ टेक्स्टफील्ड दिखाता है, और यदि मैं "बी" को "डी" में बदलता हूं, तो केवल "डी" वापस भेजा जाता है

closedDialog: {description: "d"}

जिसका अर्थ है कि एप्लिकेशन ऑब्जेक्ट को खाली करने के लिए रीसेट कर दिया गया था, लेकिन यह वह नहीं है जो दिखाया गया है ... तो, मैं अपडेट को कैसे ट्रिगर करूं? मैंने विभिन्न "अपडेट", "अनुरोध अपडेट" .. और ऐसे जीवन चक्र विधियों का प्रयास किया है लेकिन इसका कोई फायदा नहीं हुआ है ..

0
Lars Borup Jensen 15 अप्रैल 2020, 13:52

1 उत्तर

सबसे बढ़िया उत्तर

mwc-textfield आंतरिक रूप से एक देशी input का उपयोग करता है और इसके लिए बाध्यकारी value संपत्ति को पास करता है। यह उन मामलों में से एक है जहां एक संपत्ति को कई स्रोतों से अपडेट किया जाता है (.value="${this.application.name}" से और पाठ को संपादित करते समय DOM से)। इस परिदृश्य में lit-html शायद यह नहीं जानते कि मूल्य को कैसे अपडेट किया जाए और डेटा और वास्तव में जो दिखाया गया है, के बीच एक गलत संरेखण का कारण बन सकता है। इसे हल करने के लिए आप live निर्देश: आईटी

पहले के बजाय लाइव DOM मान के विरुद्ध बाध्यकारी मान की जाँच करता है बाध्य मूल्य, यह निर्धारित करते समय कि मूल्य को अद्यतन करना है या नहीं।

import {live} from 'lit-html/directives/live';

// ...

render() {
  return html`
    <mwc-textfield
      .value=${live(this.application.name)}
               ^^^^
    ></mwc-textfield>
  `;
}

openDialog() में आप शायद dialog.requestUpdate˅; में कोष्ठक से चूक गए हैं, हालांकि इसे कॉल करने की कोई आवश्यकता नहीं है: this.application = {}; एक अपडेट को ट्रिगर करने के लिए पर्याप्त है।

टेक्स्टफ़ील्ड को undefined दिखाने से रोकने के लिए आप या तो बाइंडिंग में फ़ॉलबैक मान प्रदान कर सकते हैं

<mwc-textfield
  .value=${live(this.application.name || '')}
></mwc-textfield>

या संपूर्ण डेटा संरचना को खाली मानों के साथ प्रारंभ करें:

constructor() {
  this.application = {
    a: '',
    b: '',
    // ...
  };
}
0
Umbo 16 अप्रैल 2020, 08:47