Метеор: применить функцию после рендеринга вещей из mongodb

Я использую sage cell для преобразования html в математические вещи.

Template.home.rendered = function(){
  \\ apply sagecell and mathjax
}

Однако отображаемый контент поступает из монго, поэтому иногда он загружается после применения к нему ячейки sage. Я могу сделать что-то вроде этого

Template.home.rendered = function(){
  Deps.autorun(function(){
    if (Content.findOne({_id: ...})){
      \\ apply sagecell and mathjax
    }
  });
}

Стало лучше, но все равно не всегда работает. Есть ли другие вещи, которые я могу использовать, чтобы определить, что контент полностью отображается?


person user2191332    schedule 29.08.2013    source источник


Ответы (2)


Отредактировано с новым ответом:

<template name='pendingAnswer'>
    The answer to your question, coming back whenever, is:
    {{>answer}}
</template>

<template name='answer'>
    {{fromSage}}
</template>     

Template.answer.helpers({ 
    fromSage: function () {  
        Session.get('fromSage');
    }
});

Invoked whenever - from a button, from navigating to the page, on blur...        
function GetAnswerFromSage(data) {
        callHTTP(website,data, callbackFromSage)
}        

function callbackFromSage(err, data) {
        if (err) then log(err);
        Session.set('fromSage', data);
        }

Ранее: попробуйте выполнить преобразование после извлечения монго: From Meteor Doc

// An Animal class that takes a document in its constructor
Animal = function (doc) {
  _.extend(this, doc);
};
_.extend(Animal.prototype, {
  makeNoise: function () {
    console.log(this.sound);
  }
});

// Define a Collection that uses Animal as its document
Animals = new Meteor.Collection("Animals", {
  transform: function (doc) { return new Animal(doc); }
});

// Create an Animal and call its makeNoise method
Animals.insert({name: "raptor", sound: "roar"});
Animals.findOne({name: "raptor"}).makeNoise(); // prints "roar"
person Jim Mack    schedule 29.08.2013
comment
Вы предлагаете мне добавить makeNoise() в документ Content? Но тогда это было бы то же самое, что проверить, вернул ли findOne что-то ненулевое, не так ли? - person user2191332; 30.08.2013
comment
Поскольку каждый документ исходит из монго, будет вызываться ваш конструктор. Именно тогда я рекомендую вам выполнить ваши преобразования (если вы не хотите, чтобы что-то было ленивым). Вы полностью контролируете, когда он изменится, а реактивность гарантирует, что он будет быстро отрендерен. Для организации вашего кода может иметь смысл добавить это к одному или нескольким методам makeNoise. Это не добавляет его в коллекцию документов. Вам нужно будет вызвать обновления монго, чтобы выполнить это. Животное — это всего лишь ваше организационное представление, умная модель. - person Jim Mack; 30.08.2013
comment
Проблема в том, что я не могу контролировать время преобразования. Я использую внешний API, предлагаемый sagecell.sagemath.org - person user2191332; 31.08.2013
comment
Тогда использование сеанса звучит нормально. Как только вы сохраните, любой зависимый html будет обновлен. До тех пор, пока не. Так что всегда, когда вам это нужно. В вашем вопросе вы что-то делаете, когда шаблон отображается. Вместо этого сделайте что-нибудь, когда у вас будут полные данные. - person Jim Mack; 31.08.2013
comment
Да, это то, что я должен сделать. Когда я это сделал, я узнал, в чем ошибка: оказывается, скрипт, который определяет sagecell (а не тот, который запускает sagecell), должен запускаться после загрузки текста. См. подробности в ответе, который я публикую - person user2191332; 31.08.2013
comment
Рассмотрите возможность загрузки и добавления этого скрипта в свой проект. Вы можете отредактировать его, чтобы он запускался только по вашей команде. stackoverflow.com/a/18541710/953759 - person Jim Mack; 31.08.2013
comment
Проблема в том, что в этом сценарии есть другие зависимости, которые вызывают другие файлы, такие как MathJax, используя относительный путь, поэтому, я думаю, потребуется некоторая нетривиальная работа, чтобы сделать то, что вы сказали. Во всяком случае, я в порядке с тем, что это медленно на данный момент. Спасибо. - person user2191332; 01.09.2013

Сценарий

<script type='text/javascript' src="http://sagecell.sagemath.org/static/embedded_sagecell.js"></script>

который должен быть в голове, должен быть удален и вместо этого загружен после полной загрузки содержимого следующим образом:

Template.content.rendered = function(){
  // sage
  Deps.autorun(function(){
    if (Session.get('contentChanged')){
      // loading this script causes mathjax to run
      $.getScript("http://sagecell.sagemath.org/static/embedded_sagecell.js", function(d, textStatus){
        if (textStatus=='success'){
          // this converts <div class='compute'> to a sage cell
          sagecell.makeSagecell({
            inputLocation: 'div.compute',
            evalButtonText: 'Evaluate',
            hide: ['editorToggle']
          });
        }
      })
    }
  })

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

Template.content.events({
'click a': function(evt){
  evt.preventDefault();
  location.href = evt.currentTarget.href;
}
})

что делает сайт намного медленнее, к сожалению.

person user2191332    schedule 31.08.2013