Подтвердить что ты не робот

Как я мог реализовать нерегулярный заменитель даты с использованием нокаута?

Я хотел бы реализовать то, что делает этот плагин с помощью jQuery: https://github.com/rmm5t/jquery-timeago

Краткое описание этого плагина:

Это превратит все элементы abbr в класс timeago и ISO 8601 в названии (в соответствии с шаблоном проектирования даты и времени микроформат):

<abbr class="timeago" title="2011-12-17T09:24:17Z">December 17, 2011</abbr>

В чем-то вроде этого:

<abbr class="timeago" title="December 17, 2011">about 1 day ago</abbr>

Кроме использования нокаута моя разметка выглядит следующим образом:

<abbr data-bind="attr: { title: Posted }" class="timeago"></abbr>

Я думаю, что что-то не синхронизировано, потому что ничего не происходит, даже если я ставлю вызов timeago в самой модели viewmodel. Я предполагаю, что мне нужен подписчик, прикрепленный к наблюдаемому "Добавлено", но я не уверен, как это сделать.

4b9b3361

Ответ 1

Ваш подход не работает, потому что timeago создает кеш через функцию jQuery data(). Таким образом, просто обновление заголовка недостаточно.

Я думаю, что пользовательская привязка - лучший и самый чистый способ:

ko.bindingHandlers.timeago = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var $this = $(element);

        // Set the title attribute to the new value = timestamp
        $this.attr('title', value);

        // If timeago has already been applied to this node, don't reapply it -
        // since timeago isn't really flexible (it doesn't provide a public
        // remove() or refresh() method) we need to do everything by ourselves.
        if ($this.data('timeago')) {
            var datetime = $.timeago.datetime($this);
            var distance = (new Date().getTime() - datetime.getTime());
            var inWords = $.timeago.inWords(distance);

            // Update cache and displayed text..
            $this.data('timeago', { 'datetime': datetime });
            $this.text(inWords);
        } else {
            // timeago hasn't been applied to this node -> we do that now!
            $this.timeago();
        }
    }
};

Использование так же просто:

<abbr data-bind="timeago: Posted"></abbr>

Демо: http://jsfiddle.net/APRGc/1/

Ответ 2

Вот альтернатива, которая на самом деле, вероятно, не имеет никакого преимущества по сравнению с ответом Нико вообще, за исключением, возможно, более легкого прикосновения:) -

usf.ko.bindings['timeago'] = {
  update: function(element, valueAccessor) {
    var $element, date;
    date = ko.utils.unwrapObservable(valueAccessor());
    $element = $(element);
    if (date) {
      $element.attr('title', date.toISOString());
      $element.data('tiemago', false);
      return $element.timeago();
    }
  }
};