目前我们上传菜谱大部分的功能都已经实现了,但是还缺少两个部分的功能;
- 第一个是当我们上传一个菜谱的时候,我们需要重新渲染一下书签的视图;
- 第二个是当我们上传一个菜谱的时候,我们需要改变URL中的ID部分
首先我们在添加新菜谱之前重新渲染一下书签视图
- 首先我们在添加新菜谱之前重新渲染一下书签视图
js
//渲染菜谱
recipeView.render(model.state.recipe);
//成功消息
addRecipeView.renderMessage();
//重新渲染书签视图
addRecipeView.render(model.state.bookmarks);
//关于表单窗口
- 现在我们来在URL上改变ID
js
//在URL上改变ID
window.history.pushState(null, '', `#${model.state.recipe.id}`);
这两部弄完之后,我们先不用去测试,因为问题应该不大,首先我们来看一下帮助文件中的代码
- 这两部弄完之后,我们先不用去测试,因为问题应该不大,首先我们来看一下帮助文件中的代码

这里有没有方法,这两个方法十分的相似,我们这里来重构一下
-
这里有没有方法,这两个方法十分的相似,我们这里来重构一下
export const AJAX = async function (url, uploadData = undefined) {
try {
const fetchPro = uploadData
? fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(uploadData),
})
: fetch(url);
const res = await Promise.race([fetchPro, timeout(TIMEOUT_SEC)]);
const data = await res.json();
if (!res.ok) throw new Error(${data.message} (${res.status})
);
return data;
} catch (err) {
throw err;
}
}; -
修改之后的话引入的方法就要改变,然后把引入的方法变量改动一下,主要再model里面,这里就不在演示了
js
import { AJAX } from './helpers.js';
- 现在我们来测试一下


现在我们来处理一下关于用户图片的事情,我们想要用户自己上传的菜谱可以显示图标,系统自带的图片不显示
- 现在我们来处理一下关于用户图片的事情,我们想要用户自己上传的菜谱可以显示图标,系统自带的图片不显示
js
_generateMarkup() {
const id = window.location.hash.slice(1);
//this._data是搜索到的数据
return `
<li class="preview">
<a class="preview__link ${
this._data.id === id ? 'preview__link--active' : ''
}" href="#${this._data.id}">
<figure class="preview__fig">
<img src="${this._data.image}" alt="${this._data.title}" />
</figure>
<div class="preview__data">
<h4 class="preview__title">${this._data.title}</h4>
<p class="preview__publisher">${
this._data.publisher
}</p>
<div class="preview__user-generated ${
this._data.key ? '' : 'hidden'
}">
<svg>
<use href="${icons}#icon-user"></use>
</svg>
</div>
</div>
</a>
</li>`;
}
}
- 菜谱视图也是一样的
js
<svg>
<use href="${icons}#icon-plus-circle"></use>
</svg>
</button>
</div>
</div>
<div class="recipe__user-generated ${this._data.key ? '' : 'hidden'}">
<svg>
<use href="${icons}#icon-user"></use>
</svg>
</div>
<button class="btn--round btn--bookmark">
<svg class="">
<use href="${icons}#icon-bookmark${
this._data.bookmarked ? '-fill' : ''
}"></use>
</svg>
</button>
</div>


注意,想要搜索到自己添加的数据,需要再model的搜索中添加key
- 注意,想要搜索到自己添加的数据,需要再model的搜索中添加key
js
export const loadSearchResults = async function (query) {
try {
state.search.query = query;
const data = await AJAX(`${API_URL}?search=${query}&key=${KEY}`);
console.log(data);
- 为了使得侧边菜谱列表中也展现图片,我们需要再加搜索结果的时候也传入key,用来识别一下是否是用户传入的
js
state.search.results = data.data.recipes.map(rec => {
return {
id: rec.id,
title: rec.title,
publisher: rec.publisher,
image: rec.image_url,
...(rec.key && { key: rec.key }),
};
});

由于我们对表单内容做了replaceALL处理,所以可能一些成分的空格都会删除,我们来快速解决这个问题
- 由于我们对表单内容做了replaceALL处理,所以可能一些成分的空格都会删除,我们来快速解决这个问题
js
export const uploadRecipe = async function (newRecipe) {
try {
const ingredients = Object.entries(newRecipe)
.filter(entry => entry[0].startsWith('ingredient') && entry[1] !== '')
.map(ing => {
const ingArr = ing[1].split(',').map(el => el.trim());
if (ingArr.length !== 3)
throw new Error('填写的格式有误,请按照格式填写 重量, 单位, 描述');
const [quantity, unit, description] = ingArr;
return { quantity: quantity ? +quantity : null, unit, description };
});

至此,我们这个项目就结果了,无疑这个项目对一个新手来说是有些吃力,里面汇聚了关于JavaScript大量的知识点,但是你还是完成了,注意,这个项目由jona开发的,只作为学习使用