meteor - tutorial - spacebars
Meteor: Forzar la reorganización de la plantilla completa después de la actualización de la colección con Blaze (5)
Tengo una plantilla en la que se cambia el DOM, y me gustaría volver a enviar la plantilla al guardarla en la base de datos. Antes de Blaze, Meteor habría reintegrado la plantilla completa si había alguna variable reactiva en alguna parte de la plantilla, pero ahora ¿cómo puedo hacer esto?
Tengo una colección de clips configurados en una ruta de enrutador Iron:
ClipsController = RouteController.extend({
data: function() {
clips = Clips.find({}, {sort: {created: 1}});
return {clips: clips};
}
});
Y una plantilla para clips :
<template name="clips">
{{#each clips}}
{{> clip}}
{{/each}}
</template>
Entonces, tengo una plantilla para el clip :
<template name="clip">
<article class="clip" id="{{_id}}">
{{{content}}}
<ul class="tags">
{{#each tags}}
<li><a href="/#{{this}}">#{{this}}</a></li>
{{/each}}
</ul>
</article>
</template>
Y un script para esta plantilla que cambia el DOM y luego guarda el clip :
Template.clip.events({
''click .edit'': function(event, template) {
template.$(''.tags li'').each(function() {
$(this).text($(this).text().replace(/^#(.*)/, "$1"));
});
},
''click .save'': function(event, template) {
var data = {
//...
};
Clips.update({_id: this._id}, data);
// How to rerender the template ?
}
});
No creo que Blaze proporcione ninguna forma de devolver la plantilla completa, ya que Blaze tiene que tener actualizaciones detalladas.
Una forma rápida y sucia de lograr esto podría ser utilizar Session, un helper de plantilla y un bloque {{#unless}} que envuelve toda la plantilla y luego simplemente establecer la clave de sesión en true antes de la actualización y false después de causar todo en el bloque {{#unless}} para rerender.
Template.clips.noRender = function(){
return Session.get("noRender");
}
Template.clip.events({
''click .edit'': function(event, template) {
template.$(''.tags li'').each(function() {
$(this).text($(this).text().replace(/^#(.*)/, "$1"));
});
},
''click .save'': function(event, template) {
var data = {
//...
};
Session.set("noRender", true);
Clips.update({_id: this._id}, data, function(){
Session.set("noRender", false);
});
// How to rerender the template ?
}
});
<template name="clips">
{{#unless noRender}}
{{#each clips}}
{{> clip}}
{{/each}}
{{/unless}}
</template>
la acción de datos de hierro-enrutador es reactiva por defecto.
clips = Clips.find({}, {sort: {created: 1}});
reemplazar a
clips = Clips.find({}, {sort: {created: 1}}).fetch();
Creo que una mejor manera es usar Tracker.afterFlush
.
Por ejemplo:
Tracker.autorun ->
Tracker.afterFlush ->
# DOM is updated, why don''t you do something here?
Blaze proporciona una manera fácil de hacer esto:
var template = Template.instance();
var parentDom = /*where to put your Template*/;
Blaze.remove(template.view);
Blaze.render(Template.clips, parentDom);
Lo que hace es que elimina su Plantilla inválida y genera una nueva como hija. http://docs.meteor.com/#/full/blaze_remove
http://docs.meteor.com/#/full/blaze_render
Creo que esta podría ser una mejor solución también para el meteoro.
../clips.js
Template.clips.onRendered(function(){
this.autorun(function(){
Template.currentData();
});
});
template.autorun (runFunc)
Puede usar this.autorun desde una devolución de llamada onCreated o onRendered para actualizar de manera reactiva el DOM o la instancia de la plantilla. Puede usar Template.currentData () dentro de esta devolución de llamada para acceder al contexto de datos reactivos de la instancia de la plantilla.