在 setState() 触发之前,Amp-state 会被忽略
Amp-state getting ignored until setState() fired
我正在构建应根据国家/地区显示不同下载 url 的 amp 页面。通过将 isEU
组添加到 <amp-geo>
配置,我可以通过 css show/hide 适当的 <a>
元素。但是我想要的只是页面上的一个 link 变量 href。我试图通过使用来实现这一点,但我无法使用 <amp-state>
尽管它已正确生成。
在我点击 <button on="tap:AMP.setState({foo: 'amp-bind'})">Say "Hello amp-bind"</button>
之前,即使来自 amp 文档的示例也不起作用。然后它触发计算并且页面显示所有值。在此之前没有值 interpolated/calculated.
我做错了什么?
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<title>TESTPAGE</title>
<meta name="viewport"
content="width=device-width,minimum-scale=1,initial-scale=1">
<script async
src="https://cdn.ampproject.org/v0.js"></script>
<script async
custom-element="amp-geo"
src="https://cdn.ampproject.org/v0/amp-geo-0.1.js"></script>
<script async
custom-element="amp-bind"
src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<style>
[class*=-only] {
display: none;
}
.amp-geo-group-isEU .eu-only {
display: block;
}
body:not(.amp-geo-group-isEU) .non-eu-only {
display: block;
}
</style>
</head>
<body class="amp-geo-pending">
<amp-state id="stateTest"
class="i-amphtml-element i-amphtml-layout-container"
i-amphtml-layout="container"
hidden=""
aria-hidden="true">
<script type="application/json">
{
"testInitialKey": "initial state value"
}
</script>
</amp-state>
<amp-state id="myCircle"
class="i-amphtml-element i-amphtml-layout-container"
i-amphtml-layout="container"
hidden=""
aria-hidden="true">
<script type="application/json">
{
"radius": "4"
}
</script>
</amp-state>
<amp-geo layout="nodisplay">
<script type="application/json">
{
"AmpBind": true,
"ISOCountryGroups": {
"isEU": ["at", "be", "bg", "bs", "ch", "cy", "cz", "de", "dk", "ee", "es", "fi", "fr", "gb", "gr", "hr", "hu", "ie", "is", "it", "li", "lt", "lu", "lv", "mt", "nl", "no", "pl", "pt", "ro", "se", "si", "sk"]
}
}
</script>
</amp-geo>
<h1 [class]="ampGeo.isEU ? 'isEU' : 'nonEU'"
[text]="'isEU: ' + (ampGeo.isEU ? 'true' : 'false').toUpperCase()"></h1>
<h2 [text]="stateTest.testInitialKey"></h2>
<a class="eu-only"
[href]="'http://google.com/' + ampGeo.ISOCountry == 'cy' ? 'cyprusLink' : 'defaultLink'">LINK_CY</a>
<a class="non-eu-only"
href="http://google.com/?frenchLink">LINK_FR</a>
<hr>
<amp-bind-macro id="circleArea"
arguments="radius"
expression="3.14 * radius * radius"></amp-bind-macro>
<div>
The circle has an area of <span [text]="circleArea(myCircle.radius)">0</span>.
</div>
<hr>
<p [text]="'Hello ' + foo">Hello World</p>
<button on="tap:AMP.setState({foo: 'amp-bind'})">Say "Hello amp-bind"</button>
</body>
</html>
如果我理解正确,您面临的问题是 amp-bind 仅根据用户操作计算。您必须初始化初始值服务器端。这就是绑定的工作原理。这个想法是为了保证页面速度并且在页面加载时不需要运行 JavaScript。
看到这样的代码很常见
<div class="foo" [class]="x ? 'foo' : 'bar'">
也就是说,初始化 class 属性服务器端,然后在用户交互时动态更新它,这可能会导致状态更改。
但是,我可以看到这对 AMP Geo 造成的问题。服务器是否应该复制该功能以预初始化该值?例如,参见 https://github.com/ampproject/amphtml/issues/14637。听起来像你面临的同样问题。您可能想在此处添加评论以提供反馈,说明您为何希望添加某种支持。
我正在构建应根据国家/地区显示不同下载 url 的 amp 页面。通过将 isEU
组添加到 <amp-geo>
配置,我可以通过 css show/hide 适当的 <a>
元素。但是我想要的只是页面上的一个 link 变量 href。我试图通过使用来实现这一点,但我无法使用 <amp-state>
尽管它已正确生成。
在我点击 <button on="tap:AMP.setState({foo: 'amp-bind'})">Say "Hello amp-bind"</button>
之前,即使来自 amp 文档的示例也不起作用。然后它触发计算并且页面显示所有值。在此之前没有值 interpolated/calculated.
我做错了什么?
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<title>TESTPAGE</title>
<meta name="viewport"
content="width=device-width,minimum-scale=1,initial-scale=1">
<script async
src="https://cdn.ampproject.org/v0.js"></script>
<script async
custom-element="amp-geo"
src="https://cdn.ampproject.org/v0/amp-geo-0.1.js"></script>
<script async
custom-element="amp-bind"
src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<style>
[class*=-only] {
display: none;
}
.amp-geo-group-isEU .eu-only {
display: block;
}
body:not(.amp-geo-group-isEU) .non-eu-only {
display: block;
}
</style>
</head>
<body class="amp-geo-pending">
<amp-state id="stateTest"
class="i-amphtml-element i-amphtml-layout-container"
i-amphtml-layout="container"
hidden=""
aria-hidden="true">
<script type="application/json">
{
"testInitialKey": "initial state value"
}
</script>
</amp-state>
<amp-state id="myCircle"
class="i-amphtml-element i-amphtml-layout-container"
i-amphtml-layout="container"
hidden=""
aria-hidden="true">
<script type="application/json">
{
"radius": "4"
}
</script>
</amp-state>
<amp-geo layout="nodisplay">
<script type="application/json">
{
"AmpBind": true,
"ISOCountryGroups": {
"isEU": ["at", "be", "bg", "bs", "ch", "cy", "cz", "de", "dk", "ee", "es", "fi", "fr", "gb", "gr", "hr", "hu", "ie", "is", "it", "li", "lt", "lu", "lv", "mt", "nl", "no", "pl", "pt", "ro", "se", "si", "sk"]
}
}
</script>
</amp-geo>
<h1 [class]="ampGeo.isEU ? 'isEU' : 'nonEU'"
[text]="'isEU: ' + (ampGeo.isEU ? 'true' : 'false').toUpperCase()"></h1>
<h2 [text]="stateTest.testInitialKey"></h2>
<a class="eu-only"
[href]="'http://google.com/' + ampGeo.ISOCountry == 'cy' ? 'cyprusLink' : 'defaultLink'">LINK_CY</a>
<a class="non-eu-only"
href="http://google.com/?frenchLink">LINK_FR</a>
<hr>
<amp-bind-macro id="circleArea"
arguments="radius"
expression="3.14 * radius * radius"></amp-bind-macro>
<div>
The circle has an area of <span [text]="circleArea(myCircle.radius)">0</span>.
</div>
<hr>
<p [text]="'Hello ' + foo">Hello World</p>
<button on="tap:AMP.setState({foo: 'amp-bind'})">Say "Hello amp-bind"</button>
</body>
</html>
如果我理解正确,您面临的问题是 amp-bind 仅根据用户操作计算。您必须初始化初始值服务器端。这就是绑定的工作原理。这个想法是为了保证页面速度并且在页面加载时不需要运行 JavaScript。
看到这样的代码很常见
<div class="foo" [class]="x ? 'foo' : 'bar'">
也就是说,初始化 class 属性服务器端,然后在用户交互时动态更新它,这可能会导致状态更改。
但是,我可以看到这对 AMP Geo 造成的问题。服务器是否应该复制该功能以预初始化该值?例如,参见 https://github.com/ampproject/amphtml/issues/14637。听起来像你面临的同样问题。您可能想在此处添加评论以提供反馈,说明您为何希望添加某种支持。