2015-06-30 4 views
1

реф: http://jsfiddle.net/ffmqd0zz/Ractivejs декоратор непоследовательно инициализируется

HTML:

<div id='books_container'/> 

<script type='ractive/template' id="books"> 
    {{#books}} 
    <div decorator='decoration' id="{{id}}"> 
     <span> title: {{ title }}</span> 
     <span> id: {{ id }}</span> 
    </div> 
    {{/books}} 
</script> 

JavaScript:

var MyDecorator = function(node) { 
    console.log("init MyDecorator for id: " + $(node).attr('id')); 
    return { teardown: function() {}}; 
}; 

var books = new Ractive({ 
    el: '#books_container', 
    template: '#books', 
    data: {books: [{"id": 1174,"title": "franny and zoey"}, 
        {"id": 1175,"title": "moby duck"}]}, 
    decorators: { decoration: MyDecorator } 
    }); 

console.log("init complete") 

books.set('books', [{"id": 1176,"title": "life, the universe and stuff"}, 
        {"id": 1177,"title": "yellowbrick road"}, 
        {"id": 1178,"title": "grapes of wrath"} ]); 

обратите внимание, что инициализация декоратор записывается в консоль.

Когда инициализировано Ractive, два начальных элемента в списке «книги» правильно оформлены, как указано в сообщениях console.log. Однако, когда список изменяется с помощью «books.set()», Ractive только украшает третий элемент в списке, а декораторы для книг с идентификаторами 1176 и 1177 не инициализируются.

Кажется, что это оптимизация производительности, просто инициализируя декоратор на третьем добавленном элементе, пропуская первые два, даже если они были заменены.

Я делаю это неправильно или это ошибка? И может кто-нибудь предложить обходной путь, пожалуйста.

заранее спасибо

ответ

2

Ractive будет обновлять только то, что меняется. Со списками узлов ({{each}}) существуют две стратегии, используемые для обновлений:

  1. Явные модификации массива, как толчок или сращивания (или слияния) производят идентичные модификации DOM-узлов - это означает, DOM узлы остаются нетронутыми, если не изменен, в противном случае удалены или вставлен.
  2. Установка массива повторно использует узлы DOM, но даже в этом случае изменяются только те вещи, которые были изменены, со структурой каждого элемента списка.

Для декораторов, если у них нет параметров, Ractive не будет их обновлять. Один каждый способ изменить это, чтобы добавить параметр к вашему декоратора:

<div decorator='decoration:{{id}}' id="{{id}}"> 

Теперь декоратор будет снесен и инициализируется, если данные, это зависит от изменений (см http://jsfiddle.net/ffmqd0zz/2/).

Как-то документы не были обновления, НО вы также можете добавить метод update к вашему декоратора возвращаемого параметра, который будет вызываться вместо декоратора будучи torndown от параметра изменения значения:

var MyDecorator = function(node, title) { 
    console.log('new decorator', title); 
    function tooltip(title) { 
     node.title = title; 
    } 

    return { 
     teardown: function() {}, 
     update: function(title) { 
      tooltip(title); 
     } 
    }; 
    }; 

см. http://jsfiddle.net/ffmqd0zz/3/

+0

Спасибо, Марти. Ни один из ваших примеров не работал так, как я ожидал.Но они дали мне новое новое представление, из которого я смог добраться туда, где мне нужно. –

0

В качестве временного решения можно выскочить и проталкивать элементы массива по одному. See full example. Соответствующий код:

books.pop('books'); 
books.pop('books'); 

books.push('books', {"id": 1176,"title": "life, the universe and stuff"}); 
books.push('books', {"id": 1177,"title": "yellowbrick road"}); 
books.push('books', {"id": 1178,"title": "grapes of wrath"}); 

Я не уверен, что поведение, которое вы видели, связано с ошибкой или нет. Как вы сказали, это может быть эффективная оптимизация производительности. Один из них говорит о лакомых кусках от Ractive docs: «Директивы - это всего лишь инструкции для Ractive - они фактически не добавляются к элементу в качестве атрибутов».

+0

Спасибо, Кит. Хорошее обходное решение. Les –

Смежные вопросы