Skip to content
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

Implement "prepareStateForRender" — Fixes #178 #181

Merged
merged 3 commits into from
Dec 16, 2016

Conversation

yuchi
Copy link
Contributor

@yuchi yuchi commented Dec 16, 2016

Let Soy components define "prepareStateForRender" to manipulate data:

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 #178

Copy link
Contributor

@mairatma mairatma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @yuchi, this will be very useful :D

I've only added one inline comment, and besides that can you just rename your commits so that they follow the format we use? We basically write commit names as if they've started with the word If, so in your case they'd be something like: Applies source formatting, Lets ... and Add tests for "prepareStateForRender".

@@ -111,6 +112,27 @@ describe('Soy', function() {
done();
});
});

it('should pass state values to "getTemplateData" and use them in the template', function(done) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still uses the old getTemplateData name :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@yuchi
Copy link
Contributor Author

yuchi commented Dec 16, 2016

Sorry I'm used to if this commit is applied it will….

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
@yuchi yuchi force-pushed the feature-prepare-state-for-render branch from 70c4cd8 to 970e6a6 Compare December 16, 2016 09:37
@@ -60,7 +62,12 @@ class Soy extends IncrementalDomRenderer.constructor {
data[params[i]] = component[params[i]].bind(component);
}
}
return data;

if (isFunction(component.prepareStateForRender)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mairatma Didn’t want to make data mutable, so I’m branching the return here. Tell me if this is ok with you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that's fine.

@@ -11,6 +11,7 @@ import { Events as EventsComponent } from './assets/Events.soy.js';
// on it.
// TODO: We should have a better dependency management for soy files so that
// the order in which they're required doesn't matter.
import { ComputedData as ComputedDataComponent } from './assets/ComputedData.soy.js';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make sure this is the right line to place the import? I simply sorted them alphabetically.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's correct, I've just realized that this TODO isn't necessary anymore, all imports can already be in alphabetical order today :)

@@ -111,6 +112,27 @@ describe('Soy', function() {
done();
});
});

it('should pass state values to "getTemplateData" and use them in the template', function(done) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@mairatma
Copy link
Contributor

Just started reviewing :)

:octocat: Sent from GH.

Copy link
Contributor

@mairatma mairatma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot, merging now!

@@ -11,6 +11,7 @@ import { Events as EventsComponent } from './assets/Events.soy.js';
// on it.
// TODO: We should have a better dependency management for soy files so that
// the order in which they're required doesn't matter.
import { ComputedData as ComputedDataComponent } from './assets/ComputedData.soy.js';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's correct, I've just realized that this TODO isn't necessary anymore, all imports can already be in alphabetical order today :)

@@ -60,7 +62,12 @@ class Soy extends IncrementalDomRenderer.constructor {
data[params[i]] = component[params[i]].bind(component);
}
}
return data;

if (isFunction(component.prepareStateForRender)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that's fine.

@fernandosouza
Copy link
Contributor

Hey, guys. What do you think to add a documentation for this method in MetalJS website? I can do it.

cc. @yuchi, @jbalsas.

@yuchi
Copy link
Contributor Author

yuchi commented Jan 31, 2017

If you could it would be great!

@fernandosouza
Copy link
Contributor

Of course, I can. For me, it seems a Lifecycle method. Isn't it?

@yuchi
Copy link
Contributor Author

yuchi commented Jan 31, 2017

It

  • is a lifecycle method specific for Soy components
  • enables computed data without wiring events and sync* stuff
  • doesn't automatically renders on changes on computed properties so you still need to use the source properties in the template to have changes reflected in the UI (PR to solve that coming)

@fernandosouza
Copy link
Contributor

Thank you, @yuchi. I'm going to write it. 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants