Alpine: [question] How to watch property in function?

Created on 31 Mar 2020  路  3Comments  路  Source: alpinejs/alpine

Hello!

I've tried to find that on the docs and in the issues: https://github.com/alpinejs/alpine/issues?q=is%3Aissue+watch

For testing I built this little component:

<?php namespace ProcessWire;
$form = $this->modules->get('InputfieldForm');
$form->attr('x-data', 'InvoiceItem()');

$form->add([
  'type' => 'markup',
  'label' => 'Invoice',
  'value' => '<table class="uk-table uk-table-striped uk-table-small">'
    .'<thead>'
      .'<th class="right">Pos</th>'
      .'<th class="uk-width-expand">Description</th>'
      .'<th class="right min">Net</th>'
      .'<th class="right min">Gross</th>'
      .'<th class="right min">Amount</th>'
      .'<th class="right min">Total</th>'
    .'</thead>'
    .'<tbody>'
      .'<tr x-data="InvoiceItem()">'
        .'<td class="right">1</td>'
        .'<td x-text="desc"></td>'
        .'<td><input class="right min" type="number" step="10" x-model="net" @input="setNet($event.target.value)"></td>'
        .'<td><input class="right min" type="number" step="10" x-model="gross" @input="setGross($event.target.value)"></td>'
        .'<td><input class="right min" type="number" x-model="amount" @input="setAmount($event.target.value)"></td>'
        .'<td class="right min" x-text="total"></td>'
      .'</tr>'
    .'</tbody>'
    .'</table>',
]);
?>
<style>
.right { text-align: right; }
.min { min-width: 100px; }
</style>
<?= $form->render() ?>

```js

I wonder if I can somehow get rid of `this.setTotal()` calls and do that automatically whenever `net`, `gross` or `amount` changes? Not sure if that makes sense at all, just trying to get familiar with this reactive thing :)

Maybe there's something like this?

x-init="$watch('net gross amount', setTotal())"
````

Thx for your time!

Most helpful comment

Thank you @calebporzio that helps a lot :)

All 3 comments

You should be able to access $watch from a method using this.$watch

Yep, just tested with this snippet and it works fine:

<div x-data="search()" x-init="init()">
            <input type="text" x-model="search">
            <span x-ref="foo"></span>
        </div>

        <script>
            function search() {
                return {
                    search: 'hey',
                    init() {
                        this.$watch('search', value => {
                            this.$refs.foo.innerText = value
                        })
                    }
                }
            }
        </script>

Thank you @calebporzio that helps a lot :)

Was this page helpful?
0 / 5 - 0 ratings