-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Add a willRender
method to (Soy)Components
#178
Comments
This would be great to have, and I see a real need for this as well. I've seen |
Exactly. The price to pay if obviously a harder process to keep browser and server code in sync |
I’m implementing it, but I took a different approach. MutabilityFirst I don’t like having a method that can mutate the object that will be sent to the template. I’d prefer the method to act as if data would be immutable.
I personally prefer (and implemented) option N. 2. Method NameTo call the component method While I’d like to have such a lifecycle event there would be some confusion on what you can actually do in it since it’s renderer specific. Also it could cause authors to think that they should use this to compute properties on JSX components, which is a Very Bad Idea™. In my final implementation in fact it’s named |
While in JSXComponents there’s a place to compute derived values from the state just before rendering (that’s the "render" method), on Soy components there’s no way to do the same. This change makes the Soy renderer to call a "getTemplateData" method on the component passing the data that would be used for the template and trusting the implementation to do one of the following: - mutate the original template data and return it; - mutate the original template data and return undefined; - create a new object and return it (eventually mixing in the original data). Fixes metal#178
@yuchi I think this makes a lot of sense. As far as mutability goes, my preference is to avoid it when possible, but I realize that it can be a benefit for performance, so having the option is nice. I have a feeling that option three might be the most intuitive for most metal developers though. There are a few things to consider with this new feature as well. The developer needs to be aware that not all of their template data is described in their |
So the implementation will look like this: if (component.getTemplateData) {
data = object.mixin({}, data, component.getTemplateData(data));
} It would look bad in my opinion if authors would want to remove properties from the data, but since Soy templates have strict requirements regarding what you pass to them it’s almost impossible that someone will ever want to do such a thing. So I’m ok with.
If we named the method We could change the implementation so that only additional fields are kept: if (component.getAdditionalTemplateData) {
data = object.mixin({}, component.getAdditionalTemplateData(data), data); // the order!
} But this requires some analysis. I think @mairatma and @eduardolundgren need to chime in.
I though a little about this. I don’t think this is going to be a problem. In a well written component you would write the Soy template to be as “ignorant” as possible and then have the controllers do the hard work. |
I think you addressed those concerns well. The SoyDoc in your template is essentially your contract and that is defined in one place. The developer needs to just make sure that they satisfy the behavior that goes along with that, wherever that data is fulfilled. In the end I agree with you though, it should be fine. |
I think I like option 2 better as well, as that avoids us having to |
Actually the number of calls to
|
My guess is that it will mostly be used to add additional data, so that means either mutating the data object or calling |
@mthadley Exactly. |
There's also the initial "gotcha" moment when the developer forgets to |
Since @eduardolundgren proposed some names I’m gonna do a small survey here. Vote with 👍 if you like a name, 👎 if you find it confusing. Votes are closed at Thursday 15, 4pm PST. |
|
|
|
|
|
|
|
|
Votes are closed!
Thanks to this completely useless table we can now confirm the exit polls. (I’ll make a PR in a moment) |
While in JSXComponents there’s a place to compute derived values from the state just before rendering (that’s the "render" method), on Soy components there’s no way to do the same. This change makes the Soy renderer to call a "prepareStateForRender" method on the component, passing the data that would be used for the template and trusting the implementation to do one of the following: - mutate the original template data and return it; - mutate the original template data and return undefined; - create a new object and return it (eventually mixing in the original data). Fixes metal#178
While in JSXComponents there’s a place to compute derived values from the state just before rendering (that’s the "render" method), on Soy components there’s no way to do the same. This change makes the Soy renderer to call a "prepareStateForRender" method on the component, passing the data that would be used for the template and trusting the implementation to do one of the following: - mutate the original template data and return it; - mutate the original template data and return undefined; - create a new object and return it (eventually mixing in the original data). Fixes metal#178
In JSX Components there’s a simple moment to compute values to be used in the actual rendering logic:
This is completely missing in Soy components, and that means that components’ properties more or less need to be the ones you use in the Soy template.
Since in Soy is not possible to call functions to manipulate the data, this makes difficult to have properties that depend on the value of another one.
Examples include:
The proposal is to add a new
willRender
method (similar to React’scomponentWillUpdate
) that can be used to update the properties passed down to the template.The text was updated successfully, but these errors were encountered: