2012-05-01 44 views
17

Tôi đang tìm một số ví dụ để tạo một hàm tạo tùy chỉnh trên các mô hình của tôi. Tôi muốn cấu trúc mô hình/dữ liệu khác nhau sau đó chỉ cần thiết lập nó như là các thuộc tính.Nhà xây dựng tùy chỉnh Backbone.js?

Ai đó có thể chỉ cho tôi một số ví dụ cơ bản về cách thực hiện việc này không?

Cảm ơn!

+1

Bạn có thể chuyển đổi JSON của máy chủ khi cần bằng cách sử dụng 'phân tích cú pháp' (http://documentcloud.github.com/backbone/#Model-parse). Có lẽ bạn nên làm rõ những gì bạn đang cố gắng làm, một ví dụ có thể giúp đỡ. –

Trả lời

39

Nếu bạn thực sự muốn ghi đè lên các nhà xây dựng, thông qua một tài sản constructor-Backbone.Model.extend(), ví dụ:

var Klass = Backbone.Model.extend({ 

    constructor : function (attributes, options) { 

    // ... 

    } 

}); 

Nếu bạn muốn gọi các nhà xây dựng built-in từ nhà xây dựng tùy chỉnh của bạn, bạn có thể làm điều gì đó như:

var Klass = Backbone.Model.extend({ 

    constructor : function (attributes, options) { 

    Backbone.Model.apply(this, arguments); 

    } 

}); 

Hoặc nếu bạn không muốn phải lặp lại tên của va riable chứa các lớp cha mẹ trên tất cả các lớp tiểu, hoặc bạn không muốn phải lo lắng về giá trị của biến mà thay đổi, bạn có thể làm điều gì đó như sau:

var Klass; 

var parent_klass = Backbone.Model.prototype; 

(function (parent_klass) { 

    Klass = parent_klass.constructor.extend({ 

    constructor : function (attributes, options) { 

     parent_klass.constructor.apply(this, arguments); 

    } 

    }); 

})(parent_klass); 

Hoặc nếu bạn thích cách @Claude suggests, nhưng lặp lại tên biến lớp con trong lớp con thay vì tên lớp cha var name:

var Klass = Backbone.Model.extend(

    { 

    constructor : function (attributes, options) { 

     Klass.parent_klass.constructor.apply(this, arguments); 

    } 

    }, 

    { 

    parent_klass : Backbone.Model.prototype 

    } 

); 

Nếu bạn muốn có thêm lời khuyên, bạn sẽ phải cụ thể hơn về những gì bạn muốn thực hiện.

Bất cứ điều gì bạn chỉ muốn thực hiện sau chức năng xây dựng sẵn, bạn có thể thực hiện trong initialize().

+1

Hãy cẩn thận khi sử dụng __super__ kết hợp với 'this'. 'this' sẽ luôn trỏ đến đối tượng đang được tạo ra, dẫn đến một vòng lặp vô hạn. Xem trả lời của tôi để biết thêm thông tin. – Claude

+0

@Claude vâng, cảm ơn vì đã nhắc đến điều đó. Tôi đã có ý nghĩa để cập nhật lại câu trả lời: đó. Tôi đã ngừng sử dụng '__super__' kể từ khi đăng câu trả lời này. – JMM

+0

Làm thế nào về việc tạo một hàm tạo cho mỗi cá thể của một mô hình sử dụng nguyên mẫu? Tôi đã cố gắng sửa đổi phương thức khởi tạo khi một thể hiện của Backbone.Model được tạo ra. Tôi muốn thực hiện một số công việc ràng buộc tự động với khung socket.io của nút. BuT Tôi không muốn phải đính kèm một phương thức khởi tạo cho mỗi mô hình mà tôi tạo ra. Thêm một nguyên mẫu khởi tạo công trình; vấn đề duy nhất là nếu một được thông qua với mô hình nó ghi đè nó thông qua phương pháp mở rộng gạch dưới. – kr1zmo

0

Có vẻ như bạn đang tìm phương pháp initialize. Nó được gọi là khi bạn tạo ra một mô hình mới, và bạn có thể sử dụng nếu vì bất cứ điều gì bạn cần nó cho:

var myModel = Backbone.Model.extend({ 
    initialize: function() { 
    // do something besides setting attributes or model 
    alert('myModel is ready for action!'); 
    } 
}); 

new myModel(); 

Nếu bạn đang tìm kiếm để làm điều gì đó tham gia nhiều hơn, bạn có thể ghi đè lên các phương pháp constructor trong lõi Backbone. Đó là một doanh nghiệp phức tạp hơn nhiều. Tốt hơn nhiều để làm việc với các phương pháp tiếp xúc nếu bạn có thể!

+1

Tôi đang tìm một nhà xây dựng tùy chỉnh. Tôi không muốn các thuộc tính được gửi vào chỉ đơn giản được đặt trên mô hình. Tôi đang tìm cách ghi đè lên hàm tạo. – fancy

+1

Bạn có thể vượt qua một băm tùy chọn để 'khởi tạo', thao tác nó trong hàm và đặt bất kỳ thuộc tính nào bạn cần từ đó. – rjz

+0

'hàm tạo' được" hiển thị "và tài liệu giải thích cách bạn có thể ghi đè nó. 'initialize' phục vụ một mục đích khác. – Madbreaks

2

Nếu bạn muốn viết mô hình của bạn bằng cách chính mình, như thế này:

var YourModel = function() { 
    // your constructor here 
}; 

_.extend(YourModel.prototype, Backbone.Model.prototype, { 
    // your model method here 
}); 

Hãy cẩn thận, tôi nghĩ rằng bạn cần phải tham khảo ý kiến ​​Backbone.Model constructor source code. Nhưng tôi nghĩ đây không phải là một ý kiến ​​hay. Override initialize phương pháp là đúng cách:

var YourModel = Backbone.Model.extend({ 
    initialize: function (attrs, options) { 
     Backbone.Model.prototype.initialize.apply(this, arguments); // call super constructor 

     // your constructor code here 
    } 
}); 
+0

Phương thức khởi tạo 'Backbone.Model' trống, không chắc chắn có bất kỳ điểm nào trong việc gọi nó hay không. – raine

+0

@ rane bạn có chắc chắn sẽ là trường hợp trong các bản phát hành trong tương lai không? Chắc chắn khôn ngoan để gọi phương pháp siêu. – Madbreaks

6

Đây là cách tôi ghi đè mặc định Backbone.Model constructor:

Backbone.Model = (function(Model) { 
    // Define the new constructor 
    Backbone.Model = function(attributes, options) { 
    // Your constructor logic here 
    // ... 
    // Call the default constructor if you wish 
    Model.apply(this, arguments); 
    // Add some callbacks 
    this.on('event', this.myCallback, this); 
    }; 
    // Clone static properties 
    _.extend(Backbone.Model, Model);  
    // Clone prototype 
    Backbone.Model.prototype = (function(Prototype) { 
    Prototype.prototype = Model.prototype; 
    return new Prototype; 
    })(function() {}); 
    // Update constructor in prototype 
    Backbone.Model.prototype.constructor = Backbone.Model; 
    return Backbone.Model; 
})(Backbone.Model); 

Sau đó bạn phải chắc chắn rằng các nguyên mẫu Backbone.Collection sử dụng Backbone.Model constructor Cập nhật:

_.extend(Backbone.Collection.prototype, { 
    model: Backbone.Model 
}); 

'Lợi thế' của phương pháp này theo ý kiến ​​của tôi là bạn có thể tiếp tục sử dụng Backbone.Model làm phương thức khởi tạo mô hình của bạn, điều này làm cho sự thay đổi trong suốt hơn.

+1

+1 vì không làm cho mô hình của tôi mở rộng – blockhead

7

Như tôi đã đề cập trong nhận xét, hãy cẩn thận khi sử dụng this.constructor.__super__ (hoặc this.__super__), vì sợ rằng bạn sẽ kết thúc trong vòng lặp vô tận (Maximum call stack size exceeded trong Chrome).

Hãy thử như sau trong giao diện điều khiển (tự chịu rủi ro, nó sẽ dẫn đến vòng lặp vô tận vện nêu trên)

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    this.constructor.__super__.constructor.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    this.constructor.__super__.constructor.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// (8192) log: A 
// > RangeError: Maximum call stack size exceeded 

Lý do là khi tạo B, this trong constructor cho A điểm đến một instance của B , do đó, this.constructor.__super__.constructor tiếp tục trỏ về phía hàm tạo của A, được gọi là thời gian và thời gian một lần nữa.

Nếu bạn muốn "hành vi dự định", sử dụng một trong các cú pháp sau:

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    A.__super__.constructor.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    B.__super__.constructor.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// log: A 
// > A.extend.constructor 

hoặc trực tiếp mà không __super__:

var A = Backbone.Model.extend({constructor: function() { 
    console.log("log: A"); 
    Backbone.Model.apply(this, arguments); 
}}); 

var B = A.extend({constructor: function() { 
    console.log("log: B"); 
    A.apply(this, arguments); 
}}); 

new A(); 
// log: A 
// > Backbone.model.extend.constructor 
new B(); 
// log: B 
// log: A 
// > A.extend.constructor 
-1

Something phải nhận thức được khi trọng các nhà xây dựng Backbone.Model - nếu bạn không gọi Backbone.Model.apply thì Model.cid có thể không được đặt.

Rất tệ - Nếu cid không được đặt trên nhiều mô hình, bộ sưu tập có thể coi đó là bản sao của mô hình đầu tiên trong bộ sưu tập của bạn - và sẽ không cho phép thêm.

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