Обратный вызов после обновления DOM в Meteor.js

У меня есть проект Meteor:https://github.com/jfahrenkrug/code_buddy

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

Я хотел бы автоматически запускать функцию highlightSyntax, когда код был изменен, но на самом деле он не работает.

Я пробовал query.observe, но это не сработало: выделение синтаксиса вспыхнуло один раз, а затем снова исчезло.

Итак, мой вопрос: как запустить код после обновления DOM?

Ответы на вопрос(9)

который, кажется, работает довольно хорошо:

Template.myTemplate.onRendered(function() {
    this.autorun(function() {
        Meteor.setTimeout(function() {
            // DOM has been updated
        }, 1);
    });
});

Я не являюсь экспертом в Метеоре, поэтому у него могут быть некоторые недостатки, но я пока не нашел ни одного », # x2014; кроме того, что это немного грязно!

Meteor.startup(callback)

увидетьhttp://docs.meteor.com/#meteor_startup

 Johannes Fahrenkrug12 апр. 2012 г., 07:53
Спасибо, но речь не идет о том, когда DOM готов к загрузке страницы. Мне нужно знать, когда DOM завершит обновление из-за измененных данных, поступающих с сервера.
 05 нояб. 2012 г., 13:38
Это было бы недостаточно, как отметил Йоханнес.

однако вы можете принудительно принудительно выполнить все ожидающие обновления DOM с помощьюTracker.flush().

После звонкаflush()вы знаете, что DOM обновлен, и поэтому вы можете выполнять любые необходимые изменения DOM вручную.

 12 апр. 2012 г., 09:27
Было бы здорово иметь такую функцию. Что-то вродеTemplate.myView.onFlush(function() {}) или специальное событие. Например, только сейчас я ищу способ установки полосы прокрутки элемента при каждом обновлении. Является ли это возможным? Спасибо
 12 апр. 2012 г., 10:32
Другой случай: предположим, что я отображаю шаблон на узлах DOM сvar frag = Meteor.ui.render(Template.myView), но затем подождите несколько секунд, прежде чем вставитьfrag на страницу. Считаете ли вы, что новый обратный вызов должен запускаться во время визуализации шаблона в узлах DOM или во время вывода этих узлов DOM на экран? (Первое легко, второе действительно сложно ..)
 12 апр. 2012 г., 10:30
@LarZuK Выступая в качестве одного из разработчиков Meteor (я думаю, что мы все разработчики, но я имею в виду первоначальную команду из 4 :)), я думаю, что это отличная идея, и я часто хотел что-то подобное, но я Я не уверен, как это должно работать. У вас есть предложение, что должно произойти, если я наберуconsole.log(Template.myView()) в консоль? Просто никогда не вызывать функцию в этом случае?

Blaze Компоненты (Я один из авторов) у вас есть API, который вызывает методы при вставке, перемещении или удалении DOM. ы можетепосмотреть здесь как сделать реактивную переменную при изменении DOM.

Недостатком этого подхода является то, что он не изменяется при изменении атрибутов элемента DOM (например,class менять). Только когда сами элементы DOM изменены. Это работает для большинства случаев, но если вам нужно второе, я предлагаю вам просто использоватьMutationObserver, этом случае вы сможете реагировать и на внешние изменения.

Template.myTemplate.rendered обеспечивает обратный вызов, который

is called once when an instance of Template.myTemplate is rendered into DOM nodes and put into the document for the first time.

Больше информации наhttp://docs.meteor.com/#template_rendered

 20 мая 2014 г., 08:24
В наши дни это действительно не работает. Увидетьgroups.google.com/forum/#!msg/meteor-talk/47Orrrz7kjg/…
 10 дек. 2014 г., 03:51
Этот обратный вызов не будет вызываться при обновлении DOM, например когда новый элемент добавляется к{{#each}} в шаблоне. Он будет называться только & quot;once когда экземпляр Template.myTemplate отображается в узлах DOM и помещается в документ в первый раз. & quot;
Решение Вопроса

foo.html

<template name="mytemplate">
  <div id="my-magic-div">
    .. stuff goes here ..
    {{add_my_special_behavior}}
  </div>
</template>

foo.js

Template.mytemplate.add_my_special_behavior = function () {
  Meteor.defer(function () {
    // find #my-magic-div in the DOM
    // do stuff to it
  });
  // return nothing
};

Функция будет вызываться всякий раз, когда шаблон визуализируется (или повторно обрабатывается), так что вы можете использовать его как ловушку для выполнения любых специальных манипуляций с DOM, которые вы хотите выполнить. Вам нужно использовать Meteor.defer (который делает то же самое, что и settimeout (f, 0)), потому что во время визуализации шаблона он еще не находится в DOM.

Имейте в виду, что вы можете визуализировать шаблон, не вставляя его в DOM! Например, это абсолютно законно:

console.log(Template.mytemplate())

Поэтому, когда шаблон отображается, нет 100% гарантии, что он окажется в DOM. Это зависит от пользователя шаблона.

 01 мая 2012 г., 22:59
Хм ... может быть, это так, потому что Feed.find () сначала должен получить данные из модели Feed? Может быть, даже с туда и обратно? На самом деле это еще не выяснилось, когда он получает данные ...
 07 янв. 2015 г., 00:50
Это все еще работает, спасибо! Теперь его нужно написать немного иначе: Template.templateName.helpers ({add_my_special_behavior: function () {...}});
 01 мая 2012 г., 22:51
У меня возникли проблемы с синхронизацией. Мне пришлось использовать очень длинный тайм-аут, равный нескольким секундам, так как кажется, что перед рендерингом все еще есть задержка.Template.contextualFeed.feedItems = -> Meteor.defer -> console.log "Template.contextualFeed.feedItems delayed" console.log $("abbr.timeago") # -> logs as [], with a additional delay it finds them $("abbr.timeago").timeago() Feed.find()
 13 мар. 2015 г., 10:54
Вы можете хотеть исходное поведение Метеора. Здесь написано:github.com/avital/meteor-ui-new-rendered-callback/blob/master/…
 Johannes Fahrenkrug12 апр. 2012 г., 17:59
Я на самом деле решил это с помощью window.setTimeout, потому что Meteor.setTimeout через исключение при вызове из query.observe.

теперь мы можем использовать.afterFlush () функция трекера.

Tracker.autorun(function(e){
   var data = Router.current().data();
   if(data.key !== undefined){
       //the data is there but dom may not be created yet
     Tracker.afterFlush(function(){
       //dom is now created.
    });
   }
});

Template.myTemplate.rendered не работает должным образом или я не понимаю ...

Мне нужно загрузить TinyMCE inline после рендеринга шаблона со всеми сообщениями, поэтому у меня есть:

- a Template
<div id="wrapper">     
         {{#each posts}}
             <div class="editable">{{post}}</div>
         {{/each}}        
  </div>
- and a Function
Template.myPosts.rendered = function(){
      console.dir($("div"));
      tinymce.init({
          selector: "div.editable",
          inline: true,
          plugins: [
              "advlist autolink lists link image charmap print preview anchor",
              "searchreplace visualblocks code fullscreen",
              "insertdatetime media table contextmenu paste"
          ],
          toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
});

}

Однако консоль регистрирует только<div id="wrapper"> а не<div class="editable"> div, которые содержат мои сообщения. Ну, это похожеTemplate.myTemplate.rendered обратный вызов происходит до того, как шаблон отображается, верно?

РЕДАКТИРОВАТЬ: я поставилTemplate.myTemplate.rendered код внутриsetTimeout() и все вроде работает, так что я уверенTemplate.myTemplate.rendered вызывает проблему.

но через два года можно было бы интегрироватьбиблиотека оперативного преобразования с Meteor и используйте Ace или CodeMirror на клиенте, который автоматически выделяет синтаксис. Это дает дополнительное преимущество, позволяя людям редактировать одновременно.

Я уже сделал всю работу за вас :)

Ваш ответ на вопрос