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
amp-bind: Support changing src
on amp-list
#8735
Conversation
<strong>Unit Price</strong>: ${{unitPrice}} | ||
</template> | ||
</amp-list> | ||
</body> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you build a paginated sorting/filtering demo as a template for ampbyexample?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, let's discuss more offline
extensions/amp-list/0.1/amp-list.js
Outdated
/** @override */ | ||
mutatedAttributesCallback(mutations) { | ||
const srcMutation = mutations['src']; | ||
if (srcMutation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mutations['src'] !== undefined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
extensions/amp-list/0.1/amp-list.js
Outdated
@@ -82,6 +114,11 @@ export class AmpList extends AMP.BaseElement { | |||
} | |||
}); | |||
} | |||
|
|||
/** @return {Promise} */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@visibleForTesting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
b6dd0f0
to
3b07ecb
Compare
/to @aghassemi |
<button on="tap:AMP.setState({listSrc:'/list/fruit-data/get'})">Show Fruit</button> | ||
<button on="tap:AMP.setState({listSrc:'/list/vegetable-data/get'})">Show Vegetables</button> | ||
|
||
<amp-list layout="responsive" src="/list/fruit-data/get" [src]="listSrc || '/list/fruit-data/get'" width="600" height="600"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is the || '/list/fruit-data/get'
part needed here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're encouraging developers to ensure that the expression for [property]
initially evaluates to the value for property
. This example is simple enough that there's no risk of unexpected behavior when bind first evaluates the expression, but it doesn't hurt to include the OR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Thanks for the explanation.
extensions/amp-list/0.1/amp-list.js
Outdated
if (srcMutation != undefined) { | ||
const p = this.populateList_(); | ||
if (getMode().test) { | ||
this.mutationPromise_ = p; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we instead try to get what we need by stubbing this.populateList_
in the test instead`?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
100% agree that this code isn't ideal. I try to avoid depending on private properties/methods when writing unit tests, hence the promise and the visibleForTesting
getter. If you think that changing it as proposed will make this easier to read / work with let me know and I'll make the change. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unit tests accessing private properties/methods is definitely fine, I prefer that over exporting specific methods/properties just for testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -66,6 +97,7 @@ export class AmpList extends AMP.BaseElement { | |||
* @private | |||
*/ | |||
rendered_(elements) { | |||
removeChildren(this.container_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the list can now become very dynamic, can you please add setAttribute('aria-live', 'polite');
to this.element
in the buildCallback
. That would let screen readers announce changes when list refreshes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, and that's on the element, not the container, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't matter for screen-readers, element
is probably better since it would allow page authors to override it (maybe they want aria-live='assertive' for certain lists).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
extensions/amp-bind/amp-bind.md
Outdated
@@ -283,6 +283,7 @@ Only binding to the following components and attributes are allowed: | |||
| `<amp-carousel type=slides>` | `[slide]`<sup>1</sup> | Changes the currently displayed slide index. [See an example](https://ampbyexample.com/advanced/image_galleries_with_amp-carousel/#linking-carousels-with-amp-bind). | |||
| `<amp-iframe>` | `[src]` | Changes the iframe's source URL. | | |||
| `<amp-img>` | `[alt]`<br>`[attribution]`<br>`[src]`<br>`[srcset]` | See corresponding [amp-img attributes](https://www.ampproject.org/docs/reference/components/media/amp-img#attributes). | | |||
| `<amp-list>` | `[src]` | Change the list's source URL. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about "Fetches JSON from the new URL and re-renders while discarding old content."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tweaked it a bit but otherwise like the parallelism with amp-state's description 👍
extensions/amp-list/0.1/amp-list.js
Outdated
|
||
/** @override */ | ||
mutatedAttributesCallback(mutations) { | ||
const srcMutation = mutations['src']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This can be inlined below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea
b2df967
to
4407f20
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review!
extensions/amp-bind/amp-bind.md
Outdated
@@ -283,6 +283,7 @@ Only binding to the following components and attributes are allowed: | |||
| `<amp-carousel type=slides>` | `[slide]`<sup>1</sup> | Changes the currently displayed slide index. [See an example](https://ampbyexample.com/advanced/image_galleries_with_amp-carousel/#linking-carousels-with-amp-bind). | |||
| `<amp-iframe>` | `[src]` | Changes the iframe's source URL. | | |||
| `<amp-img>` | `[alt]`<br>`[attribution]`<br>`[src]`<br>`[srcset]` | See corresponding [amp-img attributes](https://www.ampproject.org/docs/reference/components/media/amp-img#attributes). | | |||
| `<amp-list>` | `[src]` | Change the list's source URL. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tweaked it a bit but otherwise like the parallelism with amp-state's description 👍
extensions/amp-list/0.1/amp-list.js
Outdated
|
||
/** @override */ | ||
mutatedAttributesCallback(mutations) { | ||
const srcMutation = mutations['src']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea
This PR introduces changes to allow binding to src on
amp-list
. When the value of thesrc
attribute changes, theamp-list
element performs another XHR to get new list data and replaces the current data with the rendered results of the XHR.Reading order:
amp-list.js
for implementation changestest-amp-list.js
for updated testsvalidator-amp-list.protoascii
for validator changesbind-validator.js
for adding a new rule foramp-list
and itssrc
attributetest-bind-integration.js
for integration test changesamp-bind-integrations.html
for integration test fixture changesapp.js
To create JSON endpoints for two sets of list datalist.html
For an example of amp-list with a changeablesrc
amp-bind.md
To document addition ofamp-list
and itssrc
propertyPartial for #8700
/to @choumx