简体   繁体   中英

lit-html: issue w/ using change event to propagate changes back to data model

In the below code, i am looping through a list of my data model (this.panel), and generating an input box for each. I would like to propagate any changes made by the user back to the model. to do this i am storing the index of the item im rendering in the html element, and adding a change event handler which will update the model using that index. The problem im having is the @change event at run time is throwing an error:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'updateModel')'

What's odd is i have another event handler, updateToggleState in a check box lower down that works fine. Any thoughts on what is going on here?

Here is the code: class Panel extends LitElement { static properties = { is_fetch_on_change: {}, };

    constructor() {
        super();
        this.panel = [
                            {
                                "id": "ticker",
                                "type": "str",
                                "place_holder": "ticker (i.e. YHOO:^NDX)",
                                "value": "YHOO:^NDX",
                                "fn_param_name": "ticker"
                            },
                            {
                                "id": "st_dt",
                                "type": "datetime",
                                "place_holder": "st_dt (i.e. 2012-01-01)",
                                "value": "2012-01-01",
                                "fn_param_name": "st_dt"
                            },
                            {
                                "id": "end_dt",
                                "type": "datetime",
                                "place_holder": "end_dt (i.e. 2022-01-01)",
                                "value": "",
                                "fn_param_name": "end_dt"
                            }
                    ]
        this.is_fetch_on_change = false;
    }

    render() {
        let ret_html = []
        
        this.panel.forEach(function(c, i){
            ret_html.push(html`
                <div class="m-2">
                    <label>${c.fn_param_name}</label>
                        <input type="text" class="form-control" id = "${c.id}" placeholder="${c.place_holder}" value="${c.value}" 
                            idx="${i}" @change=${this.updateModel} />
                    </div>
                </div>
            `)
        })

        ret_html.push(html`
            <div class="m-2">
            <label class="form-check-label" for="flexCheckDefault">
                <input class="form-check-input" type="checkbox" @change=${this.updateToggleState}>
                Refresh on change
            </label>
            </div>
            <button type="submit" class="btn btn-primary m-2" ?hidden=${this.is_fetch_on_change}>Submit</button>
        `)
        return ret_html;
    }

    updateModel(e){
        let idx = e.target.getAttribute('idx');
        //add code here to update model
    }

    updateToggleState(e){
        this.is_fetch_on_change = e.target.checked;
    }
}

customElements.define('lit-panel', Panel);

Update: I was able to solve the problem of not being able to reference 'this' from within the foreach loop. i needed to basically 'pass it in'. so with that solved, i can update the specific item of the dictionary now.
However, that does not update the element or re-render it.

Using an arrow function would solve the this problem

this.panel.forEach((c, i) => {
  // `this` will be bound within here
});

Or you can use a regular for loop too.

Since panel is not specified as a reactive property, changing that will not automatically re-render the component. Perhaps you want to make that into an internal reactive state .

Keep in mind that since it is an array, just mutating it with this.panel[idx] = newValue won't trigger a re-render since the array reference will be the same. You need to create a new array reference or call this.requestUpdate() . More explained herehttps://lit.dev/docs/components/properties/#mutating-properties

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM