mustache.js форматирование даты

Я начал использовать mustache.js и до сих пор очень впечатлен. Хотя две вещи меня озадачивают. Первый ведет ко второму, так что терпите меня.

Мой JSON

{"goalsCollection": [
    {
        "Id": "d5dce10e-513c-449d-8e34-8fe771fa464a",
        "Description": "Multum",
        "TargetAmount": 2935.9,
        "TargetDate": "/Date(1558998000000)/"
    },
    {
        "Id": "eac65501-21f5-f831-fb07-dcfead50d1d9",
        "Description": "quad nomen",
        "TargetAmount": 6976.12,
        "TargetDate": "/Date(1606953600000)/"
    }
]};

Моя функция обработки

function renderInvestmentGoals(collection) {
    var tpl = '{{#goalsCollection}}<tr><td>{{Description}}</td><td>{{TargetAmount}}</td><td>{{TargetDate}}</td></tr>{{/goalsCollection}}';
    $('#tblGoals tbody').html('').html(Mustache.to_html(tpl, collection));
}

Q1. Как вы видите, мой TargetDate нуждается в разборе, но я не уверен, как это сделать в моей текущей функции.

Q2 Скажем, я хотел выполнить некоторую функцию или форматирование на одном или нескольких моих объектах перед рендерингом, каков наилучший способ сделать это?

7 ответов

Решение

Я также использовал Mustache для своих проектов из-за его способности делиться между клиентом и сервером. В итоге я отформатировал все значения (даты, валюта) в строки на стороне сервера, поэтому мне не нужно полагаться на вспомогательные функции Javascript. Это может не сработать для вас, хотя, если вы делаете логику с этими значениями на стороне клиента.

Вы также можете захотеть использовать http://handlebarsjs.com/, который по сути является Mustache, но с расширениями, которые могут помочь с форматированием на стороне клиента (и не только). Потеря здесь заключается в том, что вы, вероятно, не сможете найти серверную реализацию рулей, если это важно для вас.

Вы можете использовать "лямбда"

"TargetDate": "/Date(1606953600000)/",
"FormatDate": function() {
    return function(rawDate) {
        return rawDate.toString();
    }
}, ...

Тогда в разметке:

<td>
{{#FormatDate}}
    {{TargetDate}}
{{/FormatDate}}
</td>

По ссылке:

Когда значение является вызываемым объектом, таким как функция или лямбда, объект будет вызван и передан блок текста. Переданный текст является буквенным блоком, не обработанным.

Я создал небольшое расширение для Mustache.js, которое позволяет использовать средства форматирования внутри выражений, например {{expression | форматировщик}}

В любом случае вам необходимо создать функцию, которая анализирует ваше значение даты следующим образом:


      Mustache.Formatters = {
        date: function( str) {
          var dt = new Date( parseInt( str.substr(6, str.length-8), 10));
          return (dt.getDate() + "/" + (dt.getMonth() + 1) + "/" + dt.getFullYear());
        }
      };

А затем просто добавьте форматер в ваши выражения:

{{TargetDate | date}}

Вы можете получить код здесь: http://jvitela.github.io/mustache-wax/

Это давно, но занялся этим поиском точно так же. Мустачейс (сейчас) позволяет вам вызывать функции передаваемых данных и не только того; в функции значение this является ли любое значение истинным в разделе.

Если мой шаблон такой:

{{#names}}
    <p>Name is:{{name}}</p>
    <!-- Comment will be removed by compileTemplates.sh
         #lastLogin is an if statement if lastLogin it'll do this 
         ^lastLogin will execute if there is not lastLogin      
    -->
    {{#lastLogin}}
    <!-- 
      formatLogin is a method to format last Login 
      the function has to be part of the data sent 
      to the template
    -->
    <p>Last Login:{{formatLogin}}</p>
    {{/lastLogin}}
    {{^lastLogin}}
    not logged in yet
    {{/lastLogin}}
    {{#name}}
     passing name to it now:{{formatLogin}}
    {{/name}}
{{/names}}

И данные, как это:

var data={
    names:[
        {name:"Willy",lastLogin:new Date()}
    ],
    formatLogin:function(){
          //this is the lastDate used or name based on the block
                  //{{#name}}{{formatLogin}}{{/name}}:this is name
                  //{{#lastLogin}}{{formatLogin}}{{/lastLogin}}:this is lastLogin
          if(!/Date\]$/.test(Object.prototype.toString.call(this))){
              return "Invalid Date:"+this;
          }
          return this.getFullYear()
            +"-"+this.getMonth()+1
            +"-"+this.getDate();
    }
};
var output = Mustache.render(templates.test, data);
console.log(output);

Вы можете получить метку времени, используя простые методы String:

goalsCollection.targetDate = goalsCollection.targetDate.substring(6,18);

Конечно, это зависит от того, что ваша временная метка всегда будет одинаковой длины. Другой вариант:

goalsCollection.targetDate = 
  goalsCollection.targetDate.substring(6, goalsCollection.targetDate.length - 1);

Эти методы не являются специфичными для Усов и могут использоваться для манипулирования данными для любой библиотеки. Более подробную информацию смотрите в документации Центра разработчиков Mozilla по подстроке.

Чтобы объявить функцию в json, вы всегда можете сделать это.

var json = '{"RESULTS": true, "count": 1, "targetdate" : "/Date(1606953600000)/"}'

var obj = JSON.parse(json);
obj.newFunc = function (x) {
  return x;
}

//OUTPUT
alert(obj.newFunc(123));

Рабочий пример лямбда-функции для анализа даты ISO-8601 и форматирования в формате UTC:

Если вы хотите более красивое форматирование даты, вы можете использовать, например, что-то вроде:

      new Date().toLocaleDateString('en-GB', {
    day : 'numeric',
    month : 'short',
    year : 'numeric', hour: 'numeric', minute: 'numeric'
})
// outputs '14 Apr 2022, 11:11'
Другие вопросы по тегам