Rather than writing up a detailed answer here, I’ll just link you to a deep dive I wrote on the subject because it comes up often: Understanding args in Glimmer Components. The takeaway:
Args are values, not references. If you pass a reference type in it is of course still a reference type, but if you re-bind it like that, you’re basically “disconnecting” it from the arg, and if the parent passes a new reference to it, you will never receive it.
As a result, if you want the reactivity system to work correctly, you should basically never assign @tracked description = this.args.description: you’re not creating a two-way binding by doing that; you’re creating new reactive state in the system, which happens to start with the original value passed in.
Thus, instead of setting this.description in product-container, you would just pass it further down (e.g. <ProductPresenter @description={{@description}} />). Whoever “owns” the state (e.g. the controller) can also pass down actions to update it. Alternatively, you can pass down the model as a whole: the public API of Ember Data models is that all the attributes are reactive state.
Thank you very nice post on your blog.
I have one more question. What is the Octane way to remove old Ember’s observers? I think there is a lack in guides, but in my previous job we used to use observers very often.
Assume we have (pseudo code):
child component:
product-container.hbs
with external component KindOfInput (e.g. Wysiwig editor like TUIEditor, Froala etc.)
It is one property for value - this.value and one event onChange. It uses mut helper to change the value after each input. In our component I’d like to have action that count length of string inside the value.
It could be done by :
runnig the second action in onChange event but I didn’t find the way to run two actions from
one event or
using observer on value property or
removing mut helper.
What I did was removing of mut helper. Now I have one action that changes the value and counts length of string in component’s js file. But the question is, is it possible to use mut helper (what is preferred way to write less code for forms) to change the value and run function that e.q. counts length of text in the value?
It really depends on what you’re using the count for. If you’re using it to pass further up the UI tree, then I would just put it in that action, yep! And I think that’s actually much clearer: it keeps the action all in one place rather that having an action implicitly triggered by setting a value somewhere else!