2015-05-30 17 views
25

Các phương thức Tracker không chính xác thuộc về cốt lõi của chức năng của Meteor, hiếm khi được sử dụng trong các hướng dẫn và các sách mới bắt đầu (và nếu chúng không được giải thích rõ ràng), và kết quả được coi là "đáng sợ" hơn nhiều so với hầu hết các phần còn lại của khung công tác.Bằng tiếng Anh đơn giản, Tracker.autorun làm gì?

Tôi, vì một, chưa bao giờ xoay xở để thu xếp Tracker.autorun thành dự án của tôi vì nó dường như không bao giờ làm được những gì được mong đợi. Đây là những gì các tài liệu nói nó:

Chạy một hàm ngay bây giờ và chạy lại bất cứ khi nào phụ thuộc của nó thay đổi.

Đối với tôi điều này có vẻ giống như một cách để làm cho nguồn không phản động phản động, nhưng sau đó bạn đến với các ví dụ, là người đầu tiên trong số đó trông như thế này:

Tracker.autorun(function() { 
    var oldest = _.max(Monkeys.find().fetch(), function (monkey) { 
    return monkey.age; 
    }); 
    if (oldest) 
    Session.set("oldest", oldest.name); 
}); 

Làm thế nào chính xác này khác gì so không sử dụng Tracker.autorun? Các con trỏ đã là một nguồn phản động và làm cho các vấn đề trở nên khó hiểu hơn ví dụ tiếp theo đề cập đến một nguồn phản động khác: Phiên.

Tracker.autorun chỉ hoạt động với các nguồn phản động và nếu có thì lợi ích của việc sử dụng chúng bên trong Tracker là gì? Làm cho họ phản ứng gấp đôi?

Trả lời

33

Để thực hiện chương trình phản ứng (một biến thể của lập trình hướng sự kiện), Meteor sử dụng 2 khái niệm khác nhau:

  • tính toán phản ứng: mẩu mã mà sẽ reactively chạy lại mỗi lần phụ thuộc cơ bản của họ được sửa đổi.
  • nguồn dữ liệu phản ứng: đối tượng có khả năng đăng ký phụ thuộc khi được sử dụng bên trong tính toán phản ứng, để vô hiệu hóa nó và làm cho nó chạy lại với giá trị dữ liệu mới.

Hai khái niệm này được thực hiện bởi hai hiếm khi sử dụng cơ bản Tracker đối tượng, cụ thể là Tracker.Computation và đối tượng helper Tracker.Dependency mà là một container để lưu trữ một tập hợp các tính toán.

Một Tracker.Computation là một đối tượng với 2 phương pháp quan trọng:

  • invalidate(), mà đang gây ra việc tính toán để chạy lại.
  • onInvalidate(callback) để thực sự chạy mã tùy ý tính toán.

Khi bạn gọi Tracker.autorun, về cơ bản bạn đang tạo tính toán mới và đăng ký cuộc gọi lại onInvalidate với hàm bạn chuyển làm đối số.

A Tracker.Dependency là tập hợp các phép tính với 2 phương pháp.

  • depend(): thêm tính toán hiện tại vào tập hợp.
  • changed(): khi được gọi, làm mất hiệu lực mọi tính toán đã đăng ký.

Khi nguồn dữ liệu phản ứng đăng ký phụ thuộc bên trong tính toán, nó gọi Dependency.depend(), đơn giản là thêm tính toán hiện tại (nếu có) vào tập hợp các tính toán được theo dõi.

Khi nguồn dữ liệu phản ứng được sửa đổi, nó đang gọi Dependency.changed() sẽ làm mất hiệu lực mọi tính toán đã đăng ký trong tập hợp.

Nguồn: The Meteor Tracker manual.

Trong khung công tác Meteor, bạn thường chỉ đối phó với một số đối tượng cấp cao hơn thực hiện các khái niệm về lập trình phản ứng.

  • tính toán phản ứng được sinh ra bằng cách sử dụng Tracker.autorun, bởi trình trợ giúp mẫu mặc định luôn chạy bên trong tính toán phản ứng.
  • nguồn dữ liệu phản ứng đang sử dụng Tracker.Dependency để vô hiệu hóa tính toán, chúng bao gồm con trỏ MiniMongo, Session biến, Meteor.user(), vv ...

Sử dụng Tracker.autorun khi bạn cần phải chạy lại reactively mã tùy ý bên ngoài của mẫu người giúp đỡ, ví dụ bên trong khuôn mẫu onRendered sự kiện vòng đời, sử dụng phím tắt this.autorun (sinh sản một tính toán phản ứng tự động dừng khi mẫu bị phá hủy) để phản ứng với bất kỳ sửa đổi nguồn dữ liệu phản ứng nào.

Dưới đây là ví dụ nhỏ về mẫu đếm số lần bạn nhấp vào nút và đặt lại bộ đếm thành 0 khi được nhấp 10 lần.

HTML

<template name="counter"> 
    <div class="counter> 
    <button type="button">Click me !</button> 
    <p>You clicked the button {{count}} times.</p> 
    </div> 
</template> 

JS

Template.counter.onCreated(function(){ 
    this.count = new ReactiveVar(0); 
}); 

Template.counter.onRendered(function(){ 
    this.autorun(function(){ 
    var count = this.count.get(); 
    if(count == 10){ 
     this.count.set(0); 
    } 
    }.bind(this)); 
}); 

Template.counter.helpers({ 
    count: function(){ 
    return Template.instance().count.get(); 
    } 
}); 

Template.counter.events({ 
    "click button": function(event, template){ 
    var count = template.count.get(); 
    template.count.set(count + 1); 
    } 
}); 
+0

Great câu trả lời, nó giải quyết một vấn đề khác tôi đã có nơi ở onRendered, trong Tracker.autorun, tôi không thể có được quyền truy cập vào các mẫu sử dụng this.find ('...'). Bằng cách sử dụng this.autorun và.bind (điều này) tôi đã có thể nhận được những thứ để làm việc. Câu hỏi, là .bind (điều này) cần thiết để làm một this.find ('')? Và mục đích của nó là gì? – Aaron

+1

Vâng, đó sẽ là một câu hỏi khác trên toàn bộ nó, hãy xem: http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/ Meteor 1.2 sẽ giới thiệu các hàm hỗ trợ và hàm Arrow của ES2015, làm cho việc sử dụng cụ thể liên kết này không liên quan. https://github.com/lukehoban/es6features#arrows – saimeunt

Các vấn đề liên quan