如何利用AMP的amp-state组件实现多个setState事件以完成下拉联动过滤?
Hey 伙计!看起来你正在用AMP搭建一个支持多条件过滤的库存列表,这个需求挺实用的,我来帮你搞定多个下拉菜单的事件绑定和联动逻辑~
首先,先确认你已经在页面里引入了AMP必需的两个扩展组件:amp-state 和 amp-bind,因为AMP的动态交互完全依赖这俩:
<script async custom-element="amp-state" src="https://cdn.ampproject.org/v0/amp-state-0.1.js"></script> <script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
第一步:用amp-state管理数据和过滤状态
我们需要一个amp-state来存储从ERP拉取的原始库存数据,以及当前的过滤条件:
<amp-state id="inventoryStore"> <script type="application/json"> { "rawItems": [/* 这里放你从ERP API拿到的JSON数组数据 */], "activeFilters": { "machineType": "", "category": "", "stockStatus": "" } } </script> </amp-state>
如果你的数据是从远程API拉取的,直接给amp-state加src属性就行:<amp-state id="inventoryStore" src="/your-erp-api-endpoint"></amp-state>,AMP会自动加载并解析JSON。
第二步:给每个下拉菜单绑定change事件
每个select下拉的change事件都要触发AMP.setState来更新对应的过滤条件,关键是要保留其他已选的过滤条件,不然每次选新的下拉,之前的过滤值会被清空。这里用ES6的展开运算符...来合并状态:
<!-- 机器类型下拉 --> <select on="change:AMP.setState({ inventoryStore: { activeFilters: { ...inventoryStore.activeFilters, machineType: event.value } } })"> <option value="">所有机器类型</option> <option value="lathe">车床</option> <option value="mill">铣床</option> <!-- 其他选项 --> </select> <!-- 分类下拉 --> <select on="change:AMP.setState({ inventoryStore: { activeFilters: { ...inventoryStore.activeFilters, category: event.value } } })"> <option value="">所有分类</option> <option value="metal">金属加工</option> <option value="plastic">塑料加工</option> <!-- 其他选项 --> </select> <!-- 库存状态下拉 --> <select on="change:AMP.setState({ inventoryStore: { activeFilters: { ...inventoryStore.activeFilters, stockStatus: event.value } } })"> <option value="">所有状态</option> <option value="inStock">有库存</option> <option value="lowStock">库存不足</option> <!-- 其他选项 --> </select>
第三步:渲染过滤后的库存列表
用AMP的Handlebars风格表达式,结合amp-bind来动态渲染符合所有过滤条件的库存项:
<!-- 库存列表容器 --> <ul> {% raw %} {{#each inventoryStore.rawItems}} {{#if (and (or (empty inventoryStore.activeFilters.machineType) (eq machineType inventoryStore.activeFilters.machineType)) (or (empty inventoryStore.activeFilters.category) (eq category inventoryStore.activeFilters.category)) (or (empty inventoryStore.activeFilters.stockStatus) (eq stockStatus inventoryStore.activeFilters.stockStatus)) )}} <li> 名称: {{name}} | 类型: {{machineType}} | 状态: {{stockStatus}} | 库存: {{quantity}} </li> {{/if}} {{/each}} {% endraw %} </ul> <!-- 空状态提示 --> <p [hidden]="inventoryStore.rawItems.some(item => (inventoryStore.activeFilters.machineType === '' || item.machineType === inventoryStore.activeFilters.machineType) && (inventoryStore.activeFilters.category === '' || item.category === inventoryStore.activeFilters.category) && (inventoryStore.activeFilters.stockStatus === '' || item.stockStatus === inventoryStore.activeFilters.stockStatus) )">没有找到符合条件的库存项</p>
第四步:实现下拉菜单的联动(可选)
如果需要让下拉菜单之间联动(比如选了机器类型后,分类下拉只显示该类型对应的分类),可以用amp-state计算动态选项:
<!-- 动态生成分类选项的amp-state --> <amp-state id="filteredCategories"> <script type="application/json"> {% raw %} {{#let uniqueCats = []}} {{#each inventoryStore.rawItems}} {{#if (or (empty inventoryStore.activeFilters.machineType) (eq machineType inventoryStore.activeFilters.machineType))}} {{#unless (includes uniqueCats category)}} {{push uniqueCats category}} {{/unless}} {{/if}} {{/each}} {{uniqueCats}} {{/let}} {% endraw %} </script> </amp-state> <!-- 联动的分类下拉 --> <select on="change:AMP.setState({ inventoryStore: { activeFilters: { ...inventoryStore.activeFilters, category: event.value } } })"> <option value="">所有分类</option> {% raw %} {{#each filteredCategories}} <option value="{{this}}">{{this}}</option> {{/each}} {% endraw %} </select>
注意事项
- AMP的表达式语法是类Handlebars的,要熟悉
and、or、eq、empty这些内置辅助函数。 - 如果你用远程API拉取数据,确保CORS配置正确,AMP对跨域请求有严格要求。
- 测试的时候要使用AMP验证工具检查代码是否符合AMP规范,避免出现兼容性问题。
内容的提问来源于stack exchange,提问作者Craig Scott
相关产品推荐
相关产品推荐

