fix: 修复动作卡片点击双触发导致跳 404
- 8 个页面 exercise-card 由 bind:tap 改为 catch:tap,拦截原生 tap 冒泡 避免一次点击被『自定义事件 + 原生冒泡』触发两次, 第二次 e.detail 无 id → navigateTo detail?id=undefined → 404 - 所有 onExercise 顶部加 id 守卫,无 id 直接 return - exercise-card 点击前校验 exercise.id,缺失不触发 - detail onLoad 的 id 为空时直接显示空态,不再发起错误请求
This commit is contained in:
@@ -21,6 +21,8 @@ Component({
|
||||
},
|
||||
onTap() {
|
||||
const ex = this.data.exercise || {};
|
||||
// 防御:id 缺失时绝不跳转(避免 navigate 到 /api/exercises/undefined 触发 404)
|
||||
if (!ex || !ex.id) return;
|
||||
this.triggerEvent('tap', { id: ex.id, exercise: ex });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ Page({
|
||||
},
|
||||
|
||||
onExercise(e) {
|
||||
if (!e || !e.detail || !e.detail.id) return;
|
||||
wx.navigateTo({ url: '/pages/detail/detail?id=' + encodeURIComponent(e.detail.id) });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<view class="grid" wx:if="{{exercises.length}}">
|
||||
<view class="grid__item" wx:for="{{exercises}}" wx:key="id">
|
||||
<exercise-card exercise="{{item}}" bind:tap="onExercise" />
|
||||
<exercise-card exercise="{{item}}" catch:tap="onExercise" />
|
||||
</view>
|
||||
</view>
|
||||
<view wx:elif="{{!loading}}" class="empty">暂无数据</view>
|
||||
|
||||
@@ -69,6 +69,7 @@ Page({
|
||||
},
|
||||
|
||||
onExercise(e) {
|
||||
if (!e || !e.detail || !e.detail.id) return;
|
||||
wx.navigateTo({
|
||||
url: '/pages/detail/detail?from=collection&slug=' +
|
||||
encodeURIComponent(this.data.slug) + '&id=' + encodeURIComponent(e.detail.id)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<section-header eyebrow="EXERCISES" title="动作列表" subtitle="共 {{total}} 个动作" />
|
||||
<view class="grid" wx:if="{{exercises.length}}">
|
||||
<view class="grid__item" wx:for="{{exercises}}" wx:key="id">
|
||||
<exercise-card exercise="{{item}}" bind:tap="onExercise" />
|
||||
<exercise-card exercise="{{item}}" catch:tap="onExercise" />
|
||||
</view>
|
||||
</view>
|
||||
<view wx:elif="{{!loading}}" class="empty">该计划暂无动作</view>
|
||||
|
||||
@@ -21,6 +21,11 @@ Page({
|
||||
const id = query.id || '';
|
||||
const planId = query.planId || '';
|
||||
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 20, id, planId });
|
||||
// 防御:id 缺失直接显示空态,避免请求 /api/exercises/ 导致错乱或 404
|
||||
if (!id) {
|
||||
this.setData({ loading: false });
|
||||
return;
|
||||
}
|
||||
this.load();
|
||||
if (auth.isLogin()) {
|
||||
favSvc.exerciseStatus(id).then((r) => {
|
||||
@@ -117,6 +122,7 @@ Page({
|
||||
},
|
||||
|
||||
onExercise(e) {
|
||||
if (!e || !e.detail || !e.detail.id) return;
|
||||
wx.navigateTo({ url: '/pages/detail/detail?id=' + encodeURIComponent(e.detail.id) });
|
||||
},
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<view class="block__h eyebrow">相关推荐</view>
|
||||
<scroll-view scroll-x class="hscroll">
|
||||
<view class="hscroll__item" wx:for="{{related}}" wx:key="id">
|
||||
<exercise-card exercise="{{item}}" compact bind:tap="onExercise" />
|
||||
<exercise-card exercise="{{item}}" compact catch:tap="onExercise" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
@@ -45,6 +45,7 @@ Page({
|
||||
},
|
||||
|
||||
onExercise(e) {
|
||||
if (!e || !e.detail || !e.detail.id) return;
|
||||
if (this.data.managing) return;
|
||||
wx.navigateTo({ url: '/pages/detail/detail?id=' + encodeURIComponent(e.detail.id) });
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<view class="grid" wx:if="{{list.length}}">
|
||||
<view class="grid__item" wx:for="{{list}}" wx:key="id">
|
||||
<view class="item">
|
||||
<exercise-card exercise="{{item}}" bind:tap="onExercise" />
|
||||
<exercise-card exercise="{{item}}" catch:tap="onExercise" />
|
||||
<view wx:if="{{managing}}" class="remove" data-id="{{item.id}}" catchtap="onRemove">移除</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -81,6 +81,7 @@ Page({
|
||||
},
|
||||
|
||||
onExercise(e) {
|
||||
if (!e || !e.detail || !e.detail.id) return;
|
||||
wx.navigateTo({
|
||||
url: '/pages/detail/detail?id=' + encodeURIComponent(e.detail.id)
|
||||
});
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<section-header eyebrow="FEATURED" title="精选动作" subtitle="编辑精选 · 高效入门" action="全部" bind:action="goRecommend" />
|
||||
<scroll-view wx:if="{{featured.length}}" scroll-x class="hscroll">
|
||||
<view class="hscroll__item" wx:for="{{featured}}" wx:key="id">
|
||||
<exercise-card exercise="{{item}}" compact bind:tap="onExercise" />
|
||||
<exercise-card exercise="{{item}}" compact catch:tap="onExercise" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view wx:else class="empty">暂无数据</view>
|
||||
|
||||
@@ -42,6 +42,7 @@ Page({
|
||||
},
|
||||
|
||||
onExercise(e) {
|
||||
if (!e || !e.detail || !e.detail.id) return;
|
||||
wx.navigateTo({
|
||||
url: '/pages/detail/detail?planId=' + encodeURIComponent(this.data.id) +
|
||||
'&id=' + encodeURIComponent(e.detail.id)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<view class="list" wx:if="{{exercises.length}}">
|
||||
<view class="list__item" wx:for="{{exercises}}" wx:key="id">
|
||||
<view class="list__card">
|
||||
<exercise-card exercise="{{item}}" bind:tap="onExercise" />
|
||||
<exercise-card exercise="{{item}}" catch:tap="onExercise" />
|
||||
</view>
|
||||
<view class="list__remove" data-id="{{item.id}}" catchtap="onRemoveExercise">移除</view>
|
||||
</view>
|
||||
|
||||
@@ -86,6 +86,7 @@ Page({
|
||||
},
|
||||
|
||||
onExercise(e) {
|
||||
if (!e || !e.detail || !e.detail.id) return;
|
||||
wx.navigateTo({ url: '/pages/detail/detail?id=' + encodeURIComponent(e.detail.id) });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
exercise="{{item}}"
|
||||
score="{{item.score}}"
|
||||
reason="{{item.reason}}"
|
||||
bind:tap="onExercise" />
|
||||
catch:tap="onExercise" />
|
||||
</view>
|
||||
</view>
|
||||
<view wx:else class="empty">{{ loading ? '匹配中…' : '暂无匹配结果' }}</view>
|
||||
|
||||
@@ -57,7 +57,8 @@ Page({
|
||||
},
|
||||
|
||||
onExercise(e) {
|
||||
const id = e.detail.id;
|
||||
const id = e.detail && e.detail.id;
|
||||
if (!id) return;
|
||||
if (this.data.selectMode && this.data.planId) {
|
||||
planSvc.addExercise(this.data.planId, id).then(() => {
|
||||
wx.showToast({ title: '已添加', icon: 'success' });
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<view class="section" style="padding-top: 8rpx;">
|
||||
<view class="grid" wx:if="{{results.length}}">
|
||||
<view class="grid__item" wx:for="{{results}}" wx:key="id">
|
||||
<exercise-card exercise="{{item}}" bind:tap="onExercise" />
|
||||
<exercise-card exercise="{{item}}" catch:tap="onExercise" />
|
||||
</view>
|
||||
</view>
|
||||
<view wx:elif="{{loading}}" class="empty">搜索中…</view>
|
||||
|
||||
Reference in New Issue
Block a user