3

I have a rather complex form, and would like to make sure it works both in editing and as a "new record" form. The form's submit is actually prevented, and JSON is actually sent over. However, this is besides the point. Also, this.record is assigned on load (for editing) and an empty object for new records.

render () {
  return html`
    <form>
      <input type="text" .value="${this.record.description}">
      <input type="text" .value="${this.record.remarks}">
    </form>
  `
}

The idea is that if the form is rendered, and there is data in this.record, it will have the data pre-populated.

This assumes that this.record doesn't change under the form's butt -- if it does, the user input WILL be overwritten.

Is what I described above best practice? Or is it best NOT to use .value= and assign the fields by hand on load?

Merc
  • 16,277
  • 18
  • 79
  • 122

1 Answers1

1

There are a couple of things to be aware of here. I'm going to assume that this.record is an observed property (or has an @property decorator).

Firstly, changes to this.record.property won't cause a refresh. LitElement checks for equality but on objects it's checking the reference - you'll have to call requestUpdate directly to cause a re-render.

Secondly, if you change the value of an input LitElement won't compare to the current DOM value, but to the assigned value. If you want to compare against the DOM value use live. You can use this to ensure that changes to this.record don't update the DOM when the value added is the same.

In situations like this, where I need to submit a form or JSON to actually make a change, I use two objects - one representing the value from the server (with TS Readonly<T> constraints or Object.freeze to make sure I don't mutate it) and different one holding user changes that I can send back to the server. Then when a render happens I know what's changed (and can show that).

Keith
  • 150,284
  • 78
  • 298
  • 434