上传一个新菜谱-第一部分
上传一个新菜谱-第一部分
首先我们创建一个关于增加菜谱视图的JS文件,写一些和分页差不多的示例代码
import View from './View.js';
import icons from 'url:../../img/icons.svg';class AddRecipeView extends View {_parentElement = document.querySelector('.upload');_generateMarkup() {}
}export default new AddRecipeView();
- 之后将一些关于上传菜谱的类用变量存储起来,这个看一下HTML代码即可
import View from './View.js';
import icons from 'url:../../img/icons.svg';class AddRecipeView extends View {_parentElement = document.querySelector('.upload');_window = document.querySelector('.add-recipe-window');_overlay = document.querySelector('.overlay');_btnOpen = document.querySelector('.nav__btn--add-recipe');_btnClose = document.querySelector('.btn--close-modal');_generateMarkup() {}
}export default new AddRecipeView();
- 现在我们需要一个点击事件,用来处理当我们点击的时候将表单窗口的隐藏类给删除掉
constructor() {super();//继承父类this._addHandlerShowWindow();}_addHandlerShowWindow() {this._btnOpen.addEventListener('click',function () {this._window.classList.remove('hidden');this._overlay.classList.remove('hidden');}.bind(this));}
- 之后控制器中引入一下,不然我们的代码永远都不会执行
import * as model from './model.js';
import recipeView from './view/recipeView.js';
import searchView from './view/searchView.js';
import resultsView from './view/resultsView.js';
import bookmarksView from './view/bookmarksView.js';
import paginationView from './view/paginationView.js';
import addRecipeView from './view/addRecipeView.js';
- 现在还不能关闭这个表单窗口,现在实现关闭表单窗口的方法
constructor() {super(); //继承父类this._addHandlerShowWindow();this._addHandlerHideWindow();}_addHandlerShowWindow() {this._btnOpen.addEventListener('click',function () {this._window.classList.remove('hidden');this._overlay.classList.remove('hidden');}.bind(this));}_addHandlerHideWindow() {this._btnClose.addEventListener('click',function () {this._window.classList.add('hidden');this._overlay.classList.add('hidden');}.bind(this));}
- 这里我们将上面的方法改写,以来实现在表单窗口之外点击也可以直接关闭这个窗口,这样用户就不需要必须点击关闭窗口的这个X了
import View from './View.js';
import icons from 'url:../../img/icons.svg';class AddRecipeView extends View {_parentElement = document.querySelector('.upload');_window = document.querySelector('.add-recipe-window');_overlay = document.querySelector('.overlay');_btnOpen = document.querySelector('.nav__btn--add-recipe');_btnClose = document.querySelector('.btn--close-modal');constructor() {super(); //继承父类this._addHandlerShowWindow();this._addHandlerHideWindow();}toggleWindow() {this._overlay.classList.toggle('hidden');this._window.classList.toggle('hidden');}_addHandlerShowWindow() {this._btnOpen.addEventListener('click', this.toggleWindow.bind(this));}_addHandlerHideWindow() {this._btnClose.addEventListener('click', this.toggleWindow.bind(this));this._overlay.addEventListener('click', this.toggleWindow.bind(this));}_generateMarkup() {}
}export default new AddRecipeView();
- 我们想要获取表单的数据,这里我们使用一个比较新的Web API来获取表单数据
addHandlerUpload(handler) {this._parentElement.addEventListener('submit', function (e) {e.preventDefault();const data = [...new FormData(this)];console.log(data);handler(data);});}
注:FormData 是一个 Web API,用于构造表单数据格式的键值对,方便通过 JavaScript 发送表单数据,特别是用于 AJAX 请求或 Fetch API。
- 还是使用发布订阅者模式在控制器中进行渲染视图
//添加新食谱
const controlAddRecipe = function (newRecipe) {console.log(newRecipe);
};
const init = function () {bookmarksView.addHandlerRender(controlBookmarks);recipeView.addHandlerRender(controlRecipes);recipeView.addHandlerUpdateServings(controlServings);recipeView.addHandlerAddBookmark(controlAddBookmark);searchView.addHandlerSearch(controlSearchResults);paginationView.addHandlerClick(controlPagination);addRecipeView.addHandlerUpload(controlAddRecipe);
};init();
- 现在我们只需要点击上传的按钮就能拿到表单数据
- 之后我们讲这些数组转换为普通的对象
addHandlerUpload(handler) {this._parentElement.addEventListener('submit', function (e) {e.preventDefault();const dataArr = [...new FormData(this)];const data = Object.fromEntries(dataArr);handler(data);});}
- 但是这里还缺少一些东西,例如ID之类的东西,这些会在model中进行处理,这个将在第二部分进行处理