2012-06-13 6 views
9

Rendering Ich habe eine Vorlage, die etwa wie folgt aussieht:Run JS nach einem Meteor Vorlage

<template name="foo"> 
    <textarea name="text">{{contents}}</textarea> 
</template> 

ich machen es mit:

Template.foo = function() { 
    return Foos.find(); 
} 

Und ich habe einige Event-Handler:

Template.foo.events = { 
    'blur textarea': blurHandler 
} 

Was ich tun möchte, ist das rows Attribut der textarea abhängig von der Größe des Inhalts. Mir ist klar, dass ich einen Handlebars-Helfer schreiben könnte, aber er hätte keinen Zugriff auf das gerenderte DOM-Element, was mich zu unnötigen Duplizierungen zwingt. Im Idealfall möchte ich, dass ein Meteor ein Ereignis auslöst, nachdem ein Element gerendert wurde. Etwas wie:

Template.foo.events = { 
    'render textarea': sizeTextarea 
} 

Ist das möglich?

+0

mögliches Duplikat von [Rückruf, nachdem das DOM in Meteor.js aktualisiert wurde] (http: // stackoverflow.com/questions/10109788/callback-nach-der-dom-war-update-in-meteor-js) –

Antwort

15

Ich denke, der aktuelle "beste" Weg, dies zu tun (es ist ein bisschen ein Hack) ist zu verwenden Meteor.defer ala Callback after the DOM was updated in Meteor.js.

Geoff ist eine der Meteor Devs, so sein Wort Evangelium :) ist

Also in Ihrem Fall, Sie könnten so etwas wie tun:

<textarea id="{{attach_textarea}}">....</textarea> 

und

Template.foo.attach_textarea = function() { 
    if (!this.uuid) this.uuid = Meteor.uuid(); 

    Meteor.defer(function() { 
    $('#' + this.uuid).whatever(); 
    }); 

    return this.uuid; 
} 

EDIT

Beachten Sie, dass als 0.4.0 können Sie tun dies in einem viel Ad-hoc-Weise (wie von Sander wies darauf hin):

Template.foo.rendered = function() { 
    $(this.find('textarea')).whatever(); 
} 
+0

Um sicherzustellen, dass ich verstehe - gibt es nichts Magisches über eine dynamische ID hier, nur dass diese Funktion jedes Mal aufgerufen wird, wenn das Element gerendert wird? I.e. Sie könnten dies mit einem Datenattribut oder was auch immer tun? – 7zark7

+0

Hmm, 'Meteor.defer' ist nur ein Wrapper um' setTimeout (..., 0) ', oder? Dieser Ansatz ist mir aufgefallen, aber es könnte zu sichtbarem Flimmern führen. Ich brauche wirklich einen Post-Render-Haken, der der Ereignisschleife vorangeht. –

+0

Nachdem ich das gesagt habe, werde ich diese Antwort akzeptieren, weil meine Frage ein Duplikat von dem ist, mit dem du verlinkt hast (auch wenn die akzeptierte Antwort auf diesem einen weit davon entfernt ist, ideal zu sein). –

0

Ja, ich denke schon - nicht sicher, ob es „der richtige Weg“, aber das funktioniert für mich:

In Ihrer App JS, der Client Abschnitt unabhängig von Javascript dort auf dem Client ausgeführt wird. Zum Beispiel:

if (Meteor.is_client) { 
    $(function() { 
     $('textarea').attr('rows' , 12) // or whatever you need to do 
    }) 
    ... 

Hinweis des Beispiel verwendet JQuery, in dem Fall, dass Sie diese an den Client zur Verfügung stellen müssen (ich :-) denken. In meinem Fall:

Ich erstellte ein/Client-Verzeichnis und fügte jquery.js-Datei unter diesem hinzu.

Hoffe, das hilft.

+1

Das Problem ist, dass, obwohl dies bei der ersten Verlosung funktionieren könnte, es zu Problemen kommen wird, wenn das Element jemals reaktiv neu gezeichnet wird . –

+0

Oh yeah true, danke – 7zark7

+0

Ist jQuery nicht in Meteor enthalten? Ich habe keine jquery.js-Datei irgendwo und ich habe kein spezielles jQuery-Paket hinzugefügt, aber ich kann jQuery in meinen Meteor-Anwendungen gut verwenden. –

19

Ab Meteor 0.4.0 es möglich ist, zu überprüfen, ob eine Vorlage Rendering abgeschlossen ist, sehen http://docs.meteor.com/#template_rendered

Wenn ich verstehe, Ihre Frage richtig, sollten Sie Ihren Textbereich resize-Code innerhalb einer Template.foo.onRendered Funktion wickeln:

Template.foo.onRendered(function() { 
    this.attach_textarea(); 
})