我正在从 AMP 电子邮件的后端加载选项列表,并将选定的选项存储在状态变量中,该变量设置为
<input>
元素的值。我们希望默认选择第一个元素(按下按钮即可完成此操作),但我们在 AMP 电子邮件中看不到执行此操作的方法。
示例片段:
<!doctype html>
<html ⚡4email data-css-strict>
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<script custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js" async></script>
<script custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js" async></script>
<style amp4email-boilerplate>body{visibility:hidden}</style>
</head>
<body>
<amp-list
width="auto"
height="100"
layout="fixed-height"
src="https://amp.dev/static/inline-examples/data/amp-list-urls.json"
>
<template type="amp-mustache">
<div class="url-entry">
<button on="tap:AMP.setState({ selected: '{{title}}' })">{{title}}</button>
</div>
</template>
</amp-list>
<input type="text" [value]="selected" />
<button>Submit</button>
</body>
</html>
我尝试过的一些事情(这些都假设我们正在向按钮添加事件):
selected
为空时,将 selected
设置为列表响应中的第一项。但没有办法从列表中获取数据。src
初始化的 AMP State 列表中获取数据。这不适用于电子邮件上下文。amp-list
数据加载后寻找一些回调来调用 setState。据我了解,数据加载后运行的 amp-list
上没有回调。我已经读过这个问题几次了,但我仍然不确定我是否完全理解。我认为在示例片段中引用特定元素/按钮/文本而不是使用“按钮”和“第一个元素”等通用短语会很有帮助。
如果我理解正确的话,我们希望有一个输入元素,其值设置为从 JSON 端点返回的列表中的第一个字符串。我认为仅使用 amp-list 无法实现这一点,因为
amp-list 不支持 AMP 文档可以侦听的
load
事件、检索响应中的 JSON 并将 JSON 保存在供 amp-bind 读取的状态中。
AMP for Email 仅支持标准 Mustache 行为。在其他 AMP 格式中,始终使用 Mustache (mustache.js) 的 JS 实现。在 Mustache.js 中,可以使用
{{array.0}}
等语法进行随机访问来访问第一个元素。这是一个非标准 Mustache 功能,存在于 Mustache.js 中,但不一定存在于其他实现中。
结合使用 amp-list 的
single-item
和 items="."
属性并将输入放入模板中,允许 Mustache 模板将输入的默认值呈现为数组第一个元素的值。以下内容有效(并且不需要单独单击按钮来呈现默认值)如果它在 AMP Playground 中呈现,它使用 Mustache.js,但不能在 Gmail 中呈现,它只支持标准Mustache 构造并不允许随机访问数组:
<amp-list
width="auto"
height="100"
layout="fixed-height"
src="https://amp.dev/static/inline-examples/data/amp-list-urls.json"
single-item
items="."
>
<template type="amp-mustache">
{{#items}}
<div class="url-entry">
<button on="tap:AMP.setState({ selected: '{{title}}' })">{{title}}</button>
</div>
{{/items}}
<input type="text" [value]="selected ? selected : '{{items.0.title}}'" />
<button>Submit</button>
</template>
</amp-list>
defaultSelected
的属性,它是
items
的同级属性存储数组的属性:
{
"defaultSelected": "AMP YouTube Channel",
"items": [
{
"title": "AMP YouTube Channel",
"url": "https://www.youtube.com/channel/UCXPBsjgKKG2HqsKBhWA4uQw"
},
...
]
}
然后,上面的 Mustache 模板可以修改如下(仍然需要 amp-list 上的 single-item
和
items="."
):
<template type="amp-mustache">
{{#items}}
<div class="url-entry">
<button on="tap:AMP.setState({ selected: '{{title}}' })">{{title}}</button>
</div>
{{/items}}
<input type="text" [value]="{{defaultSelected}}'" />
<button>Submit</button>
</template>
默认值甚至可以通过单独的 JSON 端点公开,单独的 amp-list 可以使用该端点来与呈现选项列表的第一个 amp-list 分开呈现输入。方法2
<form method="get"
action-xhr="https://amp.gmail.dev/playground/public/ssr_amp_list"
on="submit-success: AMP.setState({'defaultSelected': event.response.items[0].name})">
<button type=submit>
Initialize
</button>
<div submit-success>
<template type="amp-mustache">
<input type="text" [value]="defaultSelected" />
</template>
</div>
</form>
(我必须将表单提交的 XHR 端点更改为 https://amp.gmail.dev/playground/public/ssr_amp_list
,因为
https://amp.dev/static/inline-examples/data/amp-list-urls.json
不适用于 Playground 中的 amp-form。它使用通配符 CORS 标头
Access-Control-Allow-Origin: *
进行响应,这是不允许的XHR 的凭证模式是
include
,这是 amp-form 在 Playground 中使用的模式。)