如何处理 Mustache 模板中的 IF 语句?

问题描述 投票:0回答:5

我在用小胡子。我正在生成通知列表。通知 JSON 对象如下所示:

[{"id":1364,"read":true,"author_id":30,"author_name":"Mr A","author_photo":"image.jpg","story":"wants to connect","notified_type":"Friendship","action":"create"}]

留着小胡子,我如何根据

notified_type
action
...做一个if语句或case语句...

如果

notified_type == "Friendship"
渲染......

如果

notified_type == "Other && action == "invite"
渲染......

这是如何运作的?

javascript templates mustache
5个回答
135
投票

刚刚看了一下小胡子文档,他们支持他们声明的“倒置部分”

如果键不存在、为假或为空列表,它们(反转部分)将被渲染

http://mustache.github.io/mustache.5.html#Inverted-Sections

{{#value}}
  value is true
{{/value}}
{{^value}}
  value is false
{{/value}}

96
投票

小胡子模板在设计上非常简单; 主页甚至说:

无逻辑模板。

所以一般的方法是在 JavaScript 中做你的逻辑并设置一堆标志:

if(notified_type == "Friendship")
    data.type_friendship = true;
else if(notified_type == "Other" && action == "invite")
    data.type_other_invite = true;
//...

然后在你的模板中:

{{#type_friendship}}
    friendship...
{{/type_friendship}}
{{#type_other_invite}}
    invite...
{{/type_other_invite}}

如果你想要一些更高级的功能,但又想保持 Mustache 的大部分简单性,你可以看看 Handlebars

Handlebars 提供了必要的功能,让您可以毫无挫折地有效构建语义模板。

Mustache 模板与 Handlebars 兼容,因此您可以使用 Mustache 模板,将其导入 Handlebars,然后开始利用额外的 Handlebars 功能。


36
投票

通常,您使用

#
语法:

{{#a_boolean}}
  I only show up if the boolean was true.
{{/a_boolean}}

目标是将尽可能多的逻辑移出模板(这是有道理的)。


21
投票

我有一个简单而通用的 hack 来执行键/值 if 语句,而不是在小胡子中仅使用布尔值(并且以一种非常可读的方式!):

function buildOptions (object) {
    var validTypes = ['string', 'number', 'boolean'];
    var value;
    var key;
    for (key in object) {
        value = object[key];
        if (object.hasOwnProperty(key) && validTypes.indexOf(typeof value) !== -1) {
            object[key + '=' + value] = true;
        }
    }
    return object;
}

有了这个 hack,一个像这样的对象:

var contact = {
  "id": 1364,
  "author_name": "Mr Nobody",
  "notified_type": "friendship",
  "action": "create"
};

变身前会是这个样子:

var contact = {
  "id": 1364,
  "id=1364": true,
  "author_name": "Mr Nobody",
  "author_name=Mr Nobody": true,
  "notified_type": "friendship",
  "notified_type=friendship": true,
  "action": "create",
  "action=create": true
};

您的小胡子模板将如下所示:

{{#notified_type=friendship}}
    friendship…
{{/notified_type=friendship}}

{{#notified_type=invite}}
    invite…
{{/notified_type=invite}}

0
投票

基于@françois-dispaux 解决方案,我编写了一个名为

prepMustache
的递归变体浏览多级对象并为所有孩子添加
key=value
键,但也:

  • hasTimexxx
    变量 timexxx 大于 00:00:00
  • var123>0
    整数变量 var123 大于 0
  • key[i]=value
    用于子数组

我还将这个函数放在全局范围内,以便在我的 Node-Red 项目中随处使用它。

const prepMustache = (function (object) {

    for (const key in object) {

        const value       = object[key];
        const keyWithVal  = `${key}=${value}`;

        // IS STRING, INT or BOOL
        if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
            
            object[keyWithVal] = true;

            // INT greater than zero
            if (typeof value === 'number' && Number.isInteger(value) && value > 0) {
                const intKeyWithValue = `${key}>${value}`;
                object[intKeyWithValue] = true;
            }

            // TIME (format 00:00:00) greater than 00:00:00
            else if (typeof value === 'string' && /^([0-9]{2}:){2}[0-9]{2}$/.test(value)) {
                const timeArray = value.split(':');
                const hours = parseInt(timeArray[0]);
                const minutes = parseInt(timeArray[1]);
                const seconds = parseInt(timeArray[2]);
                if (hours > 0 || minutes > 0 || seconds > 0) {
                    const timeKey = `has${key.charAt(0).toUpperCase() + key.slice(1)}: true`;
                    object[timeKey] = true;
                }
            }
        }

        // IS SUB-ARRAY
        else if (Array.isArray(value)) {
            value.forEach((val, i) => {
                if (typeof val === 'object') {
                    prepMustache(val);
                } else {
                    const arrKeyWithVal = `${key}[${i}]=${val}`;
                    object[arrKeyWithVal] = true;
                }
            });
        }

        // IS SUB-OBJECT
        else if (typeof value === 'object') {
            prepMustache(value);
        }
    }

    return object;
});

// Add this for NodeRed global scope only
global.set('prepMustache', prepMustache);

使用:

vars = prepMustache(vars);

使用(节点-红色):

msg.payload = global.get('prepMustache')(msg.payload)
© www.soinside.com 2019 - 2024. All rights reserved.