【问题标题】:Inserting if statement inside ES6 template literal在 ES6 模板文字中插入 if 语句
【发布时间】:2017-11-13 06:43:41
【问题描述】:

我有一个简单的 ajax 请求返回一些数据,然后插入到模板文字中。我想知道是否可以在模板中插入“if”语句?

如果 json 对象具有第 5 种颜色,则本质上是添加另一行代码。

  $.ajax({
url: 'http://localhost:8888/ColourCatchr%202/app/search.php'
}).done(function(results){
var res = jQuery.parseJSON(results);
console.log(res);
$.each(res,function(index,result){
  $('.palettes').append(`
    <div class="panel panel-default">
      <div class="panel-heading">
        <h3 class="panel-title">${result.name}</h3>
      </div>
      <div class="panel-body">
        <div class="col-md-12 colors">
          <div class="color" style=background-color:#${result['color 1']}><h6>${result['color 1']}</h6></div>
          <div class="color" style=background-color:#${result['color 2']}><h6>${result['color 2']}</h6></div>
          <div class="color" style=background-color:#${result['color 3']}><h6>${result['color 3']}</h6></div>
          <div class="color" style=background-color:#${result['color 4']}><h6>${result['color 4']}</h6></div>

          ${if(result['color 5']){
            <div class="color" style=background-color:#${result['color 5']}><h6>${result['color 5']}</h6></div>
            }
          }

          <div class="color" style=background-color:#${result['color 5']}><h6>${result['color 5']}</h6></div>
          <p>on hover change to translucent background and black text for ecah color</p>
        </div>
      </div>
      <div class="panel-footer">
          <a class="btn btn-info btn-lg" href="update.html?id=${result.id}">Edit</a>
          <a class="btn btn-danger btn-lg">Delete</a>
      </div>
    </div>`
    )
})

})

【问题讨论】:

  • "如果可以在模板中插入 'if' 语句" 不是。您只能在模板文字中使用 表达式
  • 不要在循环中附加标记。这会导致大量不必要的渲染周期,这在 JS 性能方面几乎是你能做的最糟糕的事情。使用var rows = $.map(res, function(result){ return ... })首先生成所有标记,然后使用$('.palettes').append(rows.join(''))一次附加所有生成的标记。
  • @Thomas 对此表示感谢。刚刚实现了这个,它确实工作得更好!

标签: javascript jquery ecmascript-6


【解决方案1】:

您需要将您的逻辑移动到一个函数中或使用三元运算符:

`${result['color 5'] ? 'color 5 exists!' : 'color 5 does not exist!'}`

基于评论的附加示例:

`${result['color 5'] ? 
    `<div class="color" style=background-color:#${result['color 5']}><h6>${result['color 5']}</h6></div>` 
: ''}`

【讨论】:

  • 谢谢!三元运算符工作得很好,除了我只能让它为不返回 HTML 的字符串工作。对不起这个愚蠢的问题,但我错过了什么?我需要转义某些字符吗?为了清楚起见,我试图显示以下 HTML:
    ${result['color 5'] }
    ​​>
  • 我添加了一个似乎对我有用的附加示例(我没有使用 jQuery 的 append 方法对其进行测试)。
  • 完美运行!再次感谢你。我没有意识到您需要再次使用反引号来插入 HTML。
  • @AndyGaskell 喜欢它!
【解决方案2】:

来自MDN关于模板字符串的文章:

模板文字是允许嵌入表达式的字符串文字。

因此,您还可以使用 IIFE(立即调用函数表达式)。例如:(() =&gt; { ... })().

不过,我认为如果您需要比模板字符串中的三元表达式更复杂的逻辑,您应该考虑重构您的代码。但是,由于其他答案没有提出这一点,因此这是一种使用 IIFE 的方法。这在三元表达式就足够的情况下很有用,但您更喜欢以命令形式阅读分支逻辑;或者在您嵌入其他多行模板字符串的情况下。

让我给你举个例子:

/* Note: I'm using a tagged template literal for HTML templates here, 
 * similar to the one provided by www.npmjs.com/package/lit-html. 
 */

html`
  <div class="example">
    ${(() => {
      if (result['color 5']) {
        return html`
          <div class="color-preview" style="background-color: ${result['color 5']}"></div>
          <span> Here's your color #5 </span>
        `
      } else {
        return html`<div>You don't have a 5th color</div>`
      }
    })()}
  </div>
`

由于函数体不仅可以包含表达式,因此该技术允许您在模板字符串“内”使用任何 JavaScript 语法。

【讨论】:

    【解决方案3】:

    您可以在模板文字中使用 nullish 合并运算符。

    `${result['color 5'] ?? `Color 5 exists`}`
    

    更好的方法是为函数创建默认参数。

    const renderHello = (name = "new member") => `Hello ${name}`;
    
    console.log(1, renderHello());
    console.log(2, renderHello("James"));
    // 1 Hello new member
    // 2 Hello James
    

    【讨论】:

    • 这实际上是不正确的。如果 result['color 5'] 未定义,则字符串文字呈现“未定义”。我的坏。
    • 您可以通过!!result['color 5'] 将其检查为布尔类型。
    【解决方案4】:

    要在使用ternary operator 时使用变量,请使用nested template literal,如下所示:

    let var1 = 6
    let var2 = 8
    
    console.log(`${ `${var1 > var2 ? var1 + ` (var1) `: var2 + ` (var2) `}` } is greater`)

    【讨论】:

    • SonarQube 不鼓励使用嵌套模板文字,如果您的代码库中有 sonarqube 分析,请避免使用它。 Sonarqube 分析显示“可能通过将多个模板文字嵌套在一起来构建复杂的字符串文字,因此会失去可读性和可维护性。在这种情况下,最好将嵌套模板移动到单独的语句中。”
    【解决方案5】:

    如果条件为false,有时您可能不想渲染任何内容,就像您在问题中的表现一样。因此,您可以这样做:

    (注意:当嵌套的模板文字位于${} 内时,也可以将模板文字相互嵌套)

    const html = `
      <div>
        <div>
          Lots of HTML stuff
        </div>
        <div>
    
        ${result['color 5'] && `
          <div class="color" style=background-color:#${result['color 5']}><h6>${result['color 5']}</h6></div>
        `}
      </div>
    `;
    

    之所以可行,是因为与其他语言不同,在 Javascript 中,逻辑运算符(&amp;&amp;||)不会(必然)返回 truefalse

    逻辑与运算符 (&amp;&amp;)

    Javascript 返回第一个 falsy 变量,如果没有找到,则返回最后一个 truthy 变量。

    逻辑 OR 运算符 (||)

    Javascript 返回第一个真变量,如果没有找到,则返回最后一个假变量。

    您可以在此处查看此操作:

    console.log(true && true) // true
    console.log(false && true) // false    
    console.log("a" && "b"); // b
    console.log(false && "b"); // false
    console.log(0 && "b"); // 0
    console.log("a" && NaN); // NaN

    这在 JSX 中非常常用。

    【讨论】:

      【解决方案6】:
      const heading = 'head';
      const location = 'erode';
      const district = 'erode';
      
      const isSameLocationDistrict = (location === district) || false;
      const storeSlug = `${heading} ${isSameLocationDistrict === true ? location : `${location } ${district}`}`;
      console.log(storeSlug);
      
      // "head erode"
      // "head erode1 erode"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-31
        • 1970-01-01
        • 2014-11-21
        相关资源
        最近更新 更多