如何从index.html中获取一个值,并在解析JSON文件后使用它来呈现第二个模板



我正试图了解gulp和现代JavaScript绑定。


应用程序非常简单:

  1. 将向用户显示一个html页面,用户必须在其中检查几个单选按钮
  2. 然后用户点击按钮提交他的选择
  3. 选择提交后,必须解析一个JSON文件,以便在20个可能的html页面中显示一个

我有以下(简化的(结构:

dist/
index.html
src/
scripts/
main.js
modules/
dispatchForm.js
styles/  
index.scss
templates/
index.pug
partials/
default.pug
selectors.pug
gulpfile.js
data.json

在我的gulpfile.js中,我有:

const bundler = () => {
return rollup({
input: './src/scripts/main.js',
plugins: [
babel(pkg.babel),
nodeResolve(),
commonJS(),
],
}).then((bundle) => bundle.write({
file: '.tmp/bundle.js',
format: 'umd',
sourceMap: 'inline',
}));
};
const uglify = () => {
return src('.tmp/bundle.js', {sourcemaps: true})
.pipe(plugins.uglify())
.pipe(dest('.tmp'))
.pipe(plugins.size({title: 'bundler minified'}));
};
const styles = () => {
const AUTOPREFIXER_BROWSERS = [
'ie >= 10',
'ie_mob >= 10',
'ff >= 30',
'chrome >= 34',
'safari >= 7',
'opera >= 23',
'ios >= 7',
'android >= 4.4',
'bb >= 10',
];
return src([
'src/styles/main.scss',
'src/styles/**/*.css',
])
.pipe(plugins.sassGlob())
.pipe(plugins.sass({
precision: 10,
}).on('error', plugins.sass.logError))
.pipe(plugins.autoprefixer(AUTOPREFIXER_BROWSERS))
.pipe(dest('.tmp'))
.pipe(plugins.if('*.css', plugins.cssnano()))
.pipe(dest('.tmp'))
.pipe(plugins.size({title: 'styles'}));
};
// Uses PUG as template
const templates = (env) => () => {
return src('./src/templates/*.pug')
.pipe(plugins.pug({locals: {
title: pkg.title,
description: pkg.description,
env,
}}))
.pipe(dest('dist'))
.pipe(plugins.size({title: 'templates'}));
};
const reload = (done) => {
server.reload();
return done();
};

const images = (env) => () => {
const destination = env === 'deploy' ? 'dist' : '.tmp';
return src('./src/images/**/*.{gif,jpg,png,svg}')
.pipe(dest(destination))
.pipe(plugins.size({title: 'size'}))
};

const serve = () => {
server.init({
notify: false,
logPrefix: 'WSK',
scrollElementMapping: ['main', '.mdl-layout'],
server: ['.tmp', 'dist'],
port: 3000,
});
watch(
['src/**/*.pug'],
series(templates('development'), reload)
);
watch(
['src/styles/**/*.{scss,css}'],
series(styles, templates('development'), reload)
);
watch(
['src/scripts/main.js', 'src/scripts/**/*.js'],
series(bundler, templates('development'), reload)
);
watch(
['src/images/**/*.{gif,jpg,png,svg}'],
series(images('development'), templates('development'), reload)
);
};
const clean = () => del(['.tmp', 'dist/*', '!dist/.git'], {dot: true});
exports.default = series(
clean,
bundler,
uglify,
styles,
templates('deploy'),
images('deploy')
);
exports.serve = series(
bundler,
styles,
templates('development'),
images('development'),
serve
);

我的理解是,在清理文件后,打包程序将:

  • 从我的源main.jsdispatchForm.jsscsspug模板编译后,在dist文件夹中提供html页面

Main.js

import dispatchForm from './modules/dispatchForm';
const domContentLoad = (fn) => {
if (document.readyState !== 'loading') fn();
else document.addEventListener('DOMContentLoaded', fn);
};
domContentLoad(() => {
dispatchForm();
});

dispatchForm.js

const button = document.querySelector('[data-calculator-button]');
function updateValue() {
const gain  = document.querySelector('[data-calculator-form][name="gain"]:checked');
const cost  = document.querySelector('[data-calculator-form][name="cost"]:checked');
if (gain && cost) {
button.removeAttribute('disabled');
button.classList.remove('selectors__button--inactive');
} else {
button.setAttribute('disabled', '');
button.classList.add('selectors__button--inactive');
}
}
function dispatchForm() {
const radioInput = document.querySelectorAll('[data-calculator-form]');
radioInput.forEach(element => element.addEventListener('input', updateValue));
}
export default dispatchForm;

选择器.pug

...
.selectors__form
.selectors__radio
input.selectors__input(type='radio' id='gain-points' name='gain' value='points' data-calculator-form)
label.selectors__label(for='gain-points')
.selectors__radio
input.selectors__input(type='radio' id='gain-money' name='gain' value='money' data-calculator-form)
label.selectors__label(for='gain-money')
.selectors__form
for value in [70, 80, 90, 100, 110, 120, 130]
.selectors__radio
input.selectors__input(type='radio' id=`have-${value}` name='cost' value=value data-calculator-form)
label.selectors__label(for=`have-${value}`)
| Até 
b= ` C$${value}`
button.selectors__button.selectors__button--calculate.selectors__button--inactive(disabled=true data-calculator-button)
...

上面通过gulp的"bundler"为selectors.pugmain.jsdispatchForm.js的"cost"或"gain"创建了一些选择器,并将其呈现为html


但现在我想:

  1. 使用两个按钮提交的值之一(${value}(,并将其作为参数传递给将解析JSON file的函数。

  2. 最后,解析后的JSON结果将传递给另一个pug文件


问题

  1. 如何获取此JSON(来自dispatchForm.js?来自gulpfile.js?来自pug?(并将其传递给另一个pug模板?

  2. 由于显示的JSON将使用另一个pug模板partial呈现在一个单独的html页面上,因此是否应该在单独的JS模块上处理JSON获取?为什么呢

  3. 是否应该在构建时生成所有可能的第二页html文件,并使用JS仅显示基于提交值的文件?还是应该以普通方式呈现第二个html页面?


吞咽数据

我还了解到,有一些包,比如gulp-data,用于处理json数据,我不知道它们是否是解决问题的方法。


此外,这个SO问题提示如何将pugJSON对象传递到客户端JavaScript。

您对这个问题的表述方式让我认为您的主要问题是将构建步骤与应用程序混为一谈"运行时";(在中,当用户使用您的应用程序时(,就像dispatchForm.js运行时一样。Gulp是一个生成你的项目的工具,但这是在任何用户与你的网站交互之前发生的。

你链接的SO问题是让express在";"运行时";,从架构上讲,这与在构建步骤中使用gullow非常不同。

如果我能正确理解你想要什么,我会想到有三种主要的方法。第一种是让客户端JS操作dom并适当地更改页面。您可以使用pug,通过类似于汇总插件pug(通过这个SO答案找到(的东西将其呈现到JS库中。

第二种方法是对服务器进行api调用,然后服务器会呈现一个pug模板(这就是您链接的SO问题正在做的事情(。

第三,你可以做一些事情,比如渲染出你希望用户在构建时访问的所有可能的页面,然后让dispatchForm.js将它们发送到合适的页面。在这种情况下,我建议在一个地方(比如json文件(定义这些选项,并将其作为gump管道的来源。让gullow从一个文件生成多个文件有点滑稽,但你可以找到人们做类似事情的各种方法,比如这个github线程、这个Stack Overflow答案、这个要点等等

编辑

如果你想让事情发生"一旦选择提交";,这是第一条路。因此,使用汇总插件pug,它会看起来像(完全未经测试,超出了我的想象(:

//- template.pug
.content
p= gain
p= cost
// modules/calculateButton.js
import templateFn from '../../templates/partials/template.pug';

const button = document.querySelector('[data-calculator-button]');
button.addEventListener('click', (e) => {
if (e.target.getAttribute('disabled')) return;
const gain  = document.querySelector('[data-calculator-form][name="gain"]:checked').value;
const cost  = document.querySelector('[data-calculator-form][name="cost"]:checked').value;

document.getElementById("result").innerHTML = templateFn({
gain, cost
});
});

否则,提交时不会解析任何内容。对于第三种方式的例子,我建议查看我上面发送的链接。许多构建脚本只是找到自己的方法来做一些事情,这些事情具有适当的能力/复杂性,并易于维护。

最新更新