2012-06-13 6 views
9

Tôi có một mẫu mà trông giống như sau:Run JS sau khi render một thiên thạch mẫu

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

tôi làm cho nó với:

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

Và tôi có một số xử lý sự kiện:

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

Điều tôi muốn làm là đặt thuộc tính rows của textarea tùy thuộc vào kích thước nội dung của nó. Tôi nhận ra rằng tôi có thể viết một trình trợ giúp Handlebars, nhưng nó sẽ không có quyền truy cập vào phần tử DOM được hiển thị, điều này sẽ buộc tôi phải thực hiện một số bản sao không cần thiết. Những gì tôi muốn, lý tưởng, là cho sao băng để kích hoạt một sự kiện sau khi một phần tử được hiển thị. Một cái gì đó như:

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

Điều này có thể?

+0

bản sao có thể có của [Gọi lại sau khi DOM được cập nhật trong Meteor.js] (http: // stackoverflow.com/questions/10109788/callback-sau-the-dom-được-cập nhật-in-meteor-js) –

Trả lời

15

Tôi nghĩ cách 'tốt nhất' hiện tại để thực hiện việc này (đó là một chút hack) là sử dụng Meteor.defer ala Callback after the DOM was updated in Meteor.js.

Geoff là một trong những nhà phát triển thiên thạch, vì vậy lời của Ngài là Tin Lành :)

Vì vậy, trong trường hợp của bạn, bạn có thể làm một cái gì đó như:

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

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

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

    return this.uuid; 
} 

EDIT

Lưu ý, đó là 0.4.0, bạn có thể làm này một cách nhiều ad-hoc (như được chỉ ra bởi Sander):

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

Để đảm bảo tôi hiểu - không có gì huyền diệu về việc có một id động ở đây, chỉ cần rằng chức năng này sẽ được gọi mỗi khi phần tử được hiển thị? I E. bạn có thể làm điều này với một thuộc tính dữ liệu hay bất cứ thứ gì? – 7zark7

+0

Hmm, 'Meteor.defer' chỉ là một trình bao bọc xung quanh' setTimeout (..., 0) ', phải không? Cách tiếp cận đó xảy ra với tôi, nhưng nó có thể gây ra hiện tượng nhấp nháy. Tôi thực sự cần một móc hậu xuất hiện trước vòng lặp sự kiện. –

+0

Có nói rằng, tôi sẽ chấp nhận câu trả lời này bởi vì câu hỏi của tôi là một bản sao của câu hỏi mà bạn đã liên kết tới (mặc dù câu trả lời được chấp nhận về câu hỏi đó là rất xa lý tưởng). –

0

Vâng tôi nghĩ vậy - không chắc chắn nếu đó là "đúng cách", nhưng hoạt động này đối với tôi:

Trong ứng dụng của bạn JS, phần client sẽ chạy bất cứ điều gì javascript có trên máy khách. Ví dụ:

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

Lưu ý ví dụ tại đây sử dụng JQuery, trong trường hợp này bạn cần cung cấp cho khách hàng (tôi nghĩ :-). Trong trường hợp của tôi:

Tôi đã tạo thư mục/máy khách và thêm tệp jquery.js vào phần này.

Hy vọng điều này sẽ hữu ích.

+1

Vấn đề là mặc dù điều này có thể làm việc trên bản vẽ ban đầu, nó sẽ chạy vào các vấn đề nếu phần tử bao giờ phản ứng vẽ lại . –

+0

Oh yeah true, cảm ơn – 7zark7

+0

Ngoài ra, jQuery không được bao gồm trong Meteor? Tôi không có tệp jquery.js ở bất kỳ đâu và tôi chưa thêm bất kỳ gói jQuery đặc biệt nào, nhưng tôi có thể sử dụng jQuery tốt trong các ứng dụng Meteor của tôi. –

19

Tính đến Meteor 0.4.0 nó có thể kiểm tra xem một mẫu đã kết thúc hiển thị, xem http://docs.meteor.com/#template_rendered

Nếu tôi hiểu câu hỏi của bạn một cách chính xác, bạn nên gói mã thay đổi kích thước textarea của bạn bên trong một hàm Template.foo.onRendered:

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

Kể từ khoảng tháng 6 năm 2014, cách chính xác để làm điều này đã được để thiết lập một callback sử dụng Template.myTemplate.onRendered().

+0

Nó không cháy M EI thời gian, chỉ một lần. – Egor