[LiveComponents] Hello Component JS Object
| Q | A |
|---|---|
| Bug fix? | no |
| New feature? | yes |
| Tickets | Fix None |
| License | MIT |
Hi!
This is effectively a rewrite of the LiveComponents frontend (with minimal effect on users). It introduces:
A) A Component object that "mirrors" your PHP component object and lives in a __component property of your element - this allows you to do cool things like:
const component = document.getElementById('component-id').__component
// set the firstName property and re-render
// effectively set the firstName property on your PHP object
component.firstName = 'Ryan';
// trigger the "save" LiveAction
component.save();
B) Logic is much more organized between live_controller.ts (mostly event listening & initialization), Component.ts (model+action & Ajax handling) and a number of "plugins" that add loading, polling, etc).
C) Child handling (which still has some TODOs) is more intelligent: child components will NOT re-render when their parent component re-renders, unless the data passed into the child has changed. It does this by generating a "fingerprint" (checksum) of the values that are passed into a child component when {{ component() }} is called. Then, when a parent re-renders, the "fingerprints" if its children are sent with the request. If any of those fingerprints are seen to have changed during the re-render, then we know the "input" to a child has changed and the child should be re-rendered (which is done basically by sending a signal to the child component to re-render itself with a new set of props).
TODOs:
- [x] 1) Update CHANGELOG
- [ ] 2) add some sort of
v-model(previously calleddata-model-map) ability: where a child can communicate a model change to its parent - [X] 3) BACKEND: pass
data(writable props) &propsseparately as live controller values - [x] 4) BACKEND: pass the a deterministic
data-live-idattribute to the child unless manually specified - [x] 5) BACKEND: pass a "fingerprint" value to Stimulus (fingerprint is a checksum of the values passed IN when creating a component)
- [x] 6) BACKEND: read
childrenFingerprintsdata for GET (JSON-encoded query param) and POST (request body). Use this to compare to the NEW fingerprint value for each child. If not changed, render the child as an empty element (with onlydata-live-id). If changed, render an empty element, but withdata-live-id, the new fingerprintdata-value and the newdata-live-props-value. - [ ] 7) DOCS: Add at least one new example to ux.symfony.com
- [ ] 8) DOCS: add example with data-live-id manually being set on a child so it re-renders under some situation
- [ ] 9) Find better example for the custom Stimulus controller that goes around the component in the docs
- [ ] 10) (Maybe later) a way for a child component to trigger a re-render on the parent (without a model in the parent needing to change)
Cheers!