Как работать с IF-заявлением в шаблоне с усами?

Я использую усы. Я создаю список уведомлений. Объект 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"}]

С усами, как я могу сделать заявление if или case case на основе notified_type & action...

Если notified_type == "Friendship" оказывать......

Если notified_type == "Other && action == "invite" делают.....

Как это работает?

5 ответов

Решение

Шаблоны усов по дизайну очень просты; домашняя страница даже говорит:

Шаблоны без логики.

Таким образом, общий подход заключается в том, чтобы сделать вашу логику в 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}}

Если вам нужна более продвинутая функциональность, но вы хотите сохранить большую часть простоты усов, вы можете взглянуть на Handlebars:

Рули обеспечивают необходимую мощность, позволяющую эффективно создавать семантические шаблоны без каких-либо разочарований.

Шаблоны усов совместимы с Handlebars, поэтому вы можете взять шаблон Mustache, импортировать его в Handlebars и начать пользоваться дополнительными функциями Handlebars.

Просто посмотрел документы на усы, и они поддерживают "перевернутые разделы", в которых они заявляют

они (инвертированные секции) будут отображаться, если ключ не существует, имеет значение false или является пустым списком

http://mustache.github.io/mustache.5.html

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

В общем, вы используете # синтаксис:

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

Цель состоит в том, чтобы убрать как можно больше логики из шаблона (что имеет смысл).

У меня есть простой и общий хак для выполнения оператора ключ / значение 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;
}

С этим хаком, такой объект:

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}}

Основываясь на решении @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}>0`;
                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);

используйте (Node-Red):

      msg.payload = global.get('prepMustache')(msg.payload)
Другие вопросы по тегам