una tipos pasar parametros pagina funciones funcion ejemplos ejemplo ejecutar despues desde cargar carga asincrona antes javascript meteor spacebars

javascript - tipos - ¿Cómo ejecutar una devolución de llamada después de que se haya realizado#each?



prompt javascript ejemplo (4)

No hay una manera fácil de recibir notificaciones cuando un bloque de {{#each}} ha realizado la representación en el DOM de cada elemento que se repite.

La mejor solución es usar otro cálculo reactivo ( Tracker.autorun ) para observar sus datos actuales (reactivos).

Cada vez que se modifican los datos actuales (que probablemente sea un cursor), puede ejecutar código arbitrario después de que se realicen todos los cálculos reactivos realizando su tarea, utilizando Tracker.afterFlush .

El bloque {{#each}} es uno de esos cálculos, cuya función es escuchar la fuente de datos reactiva que le da como argumento y rerender su Template.contentBlock tantas veces como elementos recuperados de la fuente que se itera, con el elemento actual como contexto de datos actual.

Al escuchar exactamente la misma fuente de datos reactiva que el {{#each}} bloqueador auxiliar y ejecutar el código DESPUÉS de que haya finalizado su propio cálculo reactivo, puede obtener el comportamiento real solicitado sin depender de algunos trucos extraños.

Aquí está la implementación completa de este patrón:

JS

Template.content.helpers({ currentData: function(){ return Template.currentData(); } }); Template.content.onRendered(function(){ this.autorun(function(){ var cursor = Template.currentData(); // we need to register a dependency on the number of documents returned by the // cursor to actually make this computation rerun everytime the count is altered var count = cursor.count(); // Tracker.afterFlush(function(){ // assert that every items have been rendered console.log(this.$("[data-cid]") == count); }.bind(this)); }.bind(this)); });

Tengo problemas con una devolución de llamada después de que #each ha terminado. Tengo una plantilla llamada "contenido":

<template name="content"> {{#if Template.subscriptionsReady}} {{#each currentData}} <div data-cid="{{this._id}}"></div> {{/each}} {{else}} Loading... {{/if}} </template>

Al principio, espero una suscripción, cuando esté disponible, repito a través de mi Colección con {{#each}} y {{#each}} el div . Lo que necesito es una especie de devolución de llamada para cuando se complete el bucle for-each (en otras palabras DOM listo).

Template.content.onRendered()

-> desencadena a principios

También intenté anexar una imagen después del {{each}} y encendí una función en su onload esta manera:

<img style="height:0;width:0" src="*mysource*" onload="callback()">

-> funcionó a veces pero no confiable de alguna manera

¿Hay alguna forma de obtener esta devolución de llamada? No tengo miedo de cambiar la estructura de esta plantilla, si eso trae la solución.


También puede usar submodelos y contar la cantidad de subpáginas que se representan. Si este número es el número de elementos en la colección, entonces todos son renderizados.

<template name="content"> {{#if Template.subscriptionsReady}} {{#each currentData}} {{> showData}} {{/each}} {{else}} Loading... {{/if}} </template> <template name="currentData"> <div data-cid="{{this._id}}"></div> </template>

Con eso, inicializa una variable reactiva y rastrearla:

var renderedCount = new ReactiveVar(0); Tracker.autorun(function checkIfAllRendered() { if(renderedCount.get() === currentData.count() && renderedCount.get() !== 0) { //allDataRendered(); } });

Cuando se currentData plantilla de datos currentData y disminuya cuando se destruya.

Template.currentData.onRendered(function() { renderedCount.set(++renderedCount.curValue); }); Template.currentData.onDestroyed(function() { renderedCount.set(--renderedCount.curValue); });


Un enfoque posiblemente más simple a considerar: cree una plantilla alrededor de su #each block y luego obtenga un evento onRendered después:

html:

<template name="content"> {{#if Template.subscriptionsReady}} {{> eachBlock}} {{else}} Loading... {{/if}} </template> <template name="eachBlock"> {{#each currentData}} <div data-cid="{{this._id}}"></div> {{/each}} </template>

js:

Template.eachBlock.onRendered(function(){ console.log("My each block should now be fully rendered!"); });


Tuve un problema similar y después de mucha búsqueda encontré la siguiente solución. Intenté usar Tracker , onRendered y otros trucos, ninguno funcionó. Esto podría considerarse más un hack, pero funciona. Desafortunadamente no recuerdo dónde encontré esta solución inicialmente.

Comience con su plantilla, pero agregue una etiqueta de plantilla después de each .

<template name="content"> {{#if Template.subscriptionsReady}} {{#each currentData}} <div data-cid="{{this._id}}"></div> {{/each}} {{doneTrigger}} {{else}} Loading... {{/if}} </template>

Luego defina un helper que devuelva nulo.

Template.content.helpers({ doneTrigger: function() { Meteor.defer(function() { // do what you need to do }); return null; } });

Puedes leer más sobre Meteor.defer() aquí , pero es equivalente a usar un setTimeout 0 milisegundos.