簡體   English   中英

如何從 index.html 獲取值並在解析 JSON 文件后使用它來呈現第二個模板?

[英]How can I get a value from index.html and use it to render a second template after parsing JSON file?

我正在嘗試圍繞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
);

根據我的理解,清理文件后,打包器將:

  • 服務於一個html頁面dist從我的編譯后的文件夾后main.jsdispatchForm.jsscsspug模板。

主程序

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)
...

上述創建的“成本”或從“增益”某些選擇selectors.pugmain.jsdispatchForm.js ,經由gulp S“捆綁”,並呈現其作為html


但現在我想:

  1. 使用兩個按鈕提交的值 ( ${value} ) 之一並將其作為參數傳遞給將解析JSON file的函數。

  2. 最后,解析后的 JSON 結果會傳遞給另一個pug文件


問題

  1. 如何獲得此JSON(從dispatchForm.js ?從gulpfile.js ?從pug原生?)並將它傳遞給另一個pug模板?

  2. JSON 獲取是否應該在單獨的 JS 模塊上處理,因為顯示的 JSON 將在單獨的 html 頁面上呈現,使用另一個 pug 模板部分? 為何如此?

  3. 如果所有可能的第二個頁面的html文件在編譯時和JS生成用於顯示僅根據所提交的價值呢? 還是應該動態呈現第二個 html 頁面?


吞咽數據

還了解到有gulp-data之類的包,用來處理json數據,不知道是不是這里的方法。


此外,這個SO 問題提示如何將pug JSON對象傳遞給客戶端 JavaScript。

您對這個問題的表述方式讓我認為您的主要問題是將構建步驟與應用程序“運行時”(例如,當用戶使用您的應用程序時)混為一談,例如何時運行 dispatchForm.js。 Gulp 是一個生成項目的工具,但這意味着在任何用戶與您的站點交互之前發生。

您鏈接的 SO 問題是在“運行時”快速渲染 pug 頁面,從架構上講,這與在 gulp 的構建步驟中發生非常不同。

如果我正確理解您想要什么,那么在我的腦海中,有 3 種主要方法可以做到。 第一種方法是讓客戶端 JS 操作 dom 並適當地更改頁面。 您可以為此使用 pug,通過rollup-plugin-pug 之類的東西呈現到 JS 庫中(通過這個SO answer找到)。

第二個將是對服務器的 api 調用,然后呈現一個 pug 模板(這是您鏈接的 SO 問題正在做的事情)。

或者第三,你可以做一些事情,比如渲染出你希望用戶在構建時訪問的所有可能的頁面,然后讓 dispatchForm.js 只是將它們發送到適當的頁面。 在這種情況下,我建議在一個地方(比如一個 json 文件)定義這些選項,並將其作為 gulp 管道的來源。 讓 gulp 從單個文件生成多個文件會有點滑稽,但是您可以找到人們通過多種方式完成類似的事情,例如這個 github 線程這個 Stack Overflow 答案這個要點等。

編輯

如果你想讓事情“根據選擇提交”發生,那就是方式 1。所以使用 rollup-plugin-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
  });
});

否則,提交時不會解析任何內容。 對於第 3 種方式的示例,我建議您查看我上面發送的鏈接。 許多構建腳本只是在尋找自己的方式來做事情,這些事情具有適當的功率/復雜性和易於維護的平衡。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM