首页 > 解决方案 > 如何将多个功能合二为一而不重复?

问题描述

在 ProdRender.js 中,我想将这三个函数合二为一,这样我就不会重复,并且应该与 ProdData.js 匹配,因为数据在 ProdData.js 中并且通过 ProdRender.js 呈现

有人可以建议我如何在不重复 prodRender.js 中的任何内容的情况下做到这一点 ProdData.js 似乎工作正常,因为我没有重复任何内容,只有 prodRender.js 是我重复三次的地方。

所以请在这里帮助我

谢谢

//ProdRender.js

function ProductDataRenderer() { }

ProductDataRenderer.prototype.render = function () {
    var nzd = 
        '<table class="table table-striped">'
        +'  <thead>'
        +'      <tr><td colspan="3">Products (NZD)</td></tr>'
        +'      <tr>'
        +'          <td>Name</td>'
        +'          <td>Price</td>'
        +'          <td>Type</td>'
        +'      </tr>'
        +'  </thead>'
        + ' <tbody>';

    var n = ProductDataConsolidator.get();
    for (var i = 0; i < n.length; i++) {
        nzd +=
            '<tr>'
        +       '<td>' + n[i].name +'</td>'
        +       '<td>' + n[i].price + '</td>'
        +       '<td>' + n[i].type + '</td>'
        +   '</tr>';
    }
    nzd += '</tbody></table>';
    document.getElementById("nzdProducts").innerHTML = nzd;

    var usd =
        '<table class="table table-striped">'
        + ' <thead>'
        + '     <tr><td colspan="3">Products (USD)</td></tr>'
        + '     <tr>'
        + '         <td>Name</td>'
        + '         <td>Price</td>'
        + '         <td>Type</td>'
        + '     </tr>'
        + ' </thead>'
        + ' <tbody>';

    var u = ProductDataConsolidator.getInUSDollars();
    for (var i = 0; i < u.length; i++) {
        usd +=
            '<tr>'
        +       '<td>' + u[i].name + '</td>'
        +       '<td>' + u[i].price + '</td>'
        +       '<td>' + u[i].type + '</td>'
        + '</tr>';
    }
    usd += '</tbody></table>';
    document.getElementById("usdProducts").innerHTML = usd;

    var euro =
        '<table class="table table-striped">'
        + ' <thead>'
        + '     <tr><td colspan="3">Products (Euro)</td></tr>'
        + '     <tr>'
        + '         <td>Name</td>'
        + '         <td>Price</td>'
        + '         <td>Type</td>'
        + '     </tr>'
        + ' </thead>'
        + ' <tbody>';

    var e = ProductDataConsolidator.getInEuros();
    for (var i = 0; i < e.length; i++) {
        euro +=
            '<tr>'
        +       '<td>' + e[i].name + '</td>'
        +       '<td>' + e[i].price + '</td>'
        +       '<td>' + e[i].type + '</td>'
        + '</tr>';
    }
    euro += '</tbody></table>';
    document.getElementById("euProducts").innerHTML = euro;
}


//ProdData.js

function ProductDataConsolidator() { }

ProductDataConsolidator.get = function (currency) {
    var l = new LawnmowerRepository().getAll();
    var p = new PhoneCaseRepository().getAll();
    var t = new TShirtRepository().getAll();
    const arr_names = [
      [l, "lawnmower"],
      [p, "Phone Case"],
      [t, "T-Shirt"],
    ]
    var products = [];
    
    let multiplier = currency == "euro"
                    ? 0.67
                    : currency == "dollar"
                    ? 0.76
                    : 1;
  
    for (let [arr,name] of arr_names){
      for (var i = 0; i < arr.length; i++) {
        products.push({
            id: arr[i].id,
            name: arr[i].name,
            price: (arr[i].price * multiplier).toFixed(2),
            type: name
        });
      }
    }
    
    return products;
}

ProductDataConsolidator.getInEuros = function(){
  return ProductDataConsolidator.get("euro");
}

ProductDataConsolidator.getInUSDollars = function(){
  return ProductDataConsolidator.get("dollar");
}

标签: javascriptarrayslist

解决方案


您需要将其分解为更小的函数并对其进行参数化

const table = (currency, content) =>
    `<table class="table table-striped">
        <thead>
            <tr><td colspan="3">Products (${currency})</td></tr>
            <tr>
                <td>Name</td>
                <td>Price</td>
                <td>Type</td>
            </tr>
        </thead>
        <tbody>
            ${content}
        </tbody>
    </table>`
;

const table_content = data => 
    data.map(({ name, price, type }) =>
        `<tr>
            <td>${name}</td>
            <td>${price}</td>
            <td>${type}</td>
        </tr>`)
    .join('\n')
;

const currencyCode = {
    dollar: 'USD',
    euro: 'Euro',
    newZealand: 'NZD'
};

function ProductDataRenderer() { }

ProductDataRenderer.prototype.render = function (currency, target) {
    const productData = ProductDataConsolidator.get(currency);
    const html = table(currencyCode[currency], table_content(productData));
    document.getElementById(target).innerHTML = html;
}

我没有改变你的代码设计,但你可以看到render做了 3 件不同的事情。它应该只呈现,而不是检索数据并将表注入 DOM。

ProductDataConsolidator使用三个具有不同名称的静态方法也没什么意义。要么创建 3 个ProductDataConsolidator仅使用一个方法get的派生类,然后将正确派生类的实例传递给它,render以便它只需要知道一个名为get的方法(顺便说一下,如果你有一个对象只有一个方法,那么它就是一个函数,为什么麻烦使用对象),或者您将产品数据直接传递给渲染(首选)


推荐阅读