Tôi cố gắng để thực hiện phiên bản của tôi về "Instance Store" trong Backbone.js như mô tả của Soundcloud trong bài đăng blog gần đây của họ:Thực hiện javascript cửa hàng dụ bằng cách trả lại ví dụ hiện tại từ constructor
http://backstage.soundcloud.com/2012/06/building-the-next-soundcloud/
liên quan Trích:
Để giải quyết điều này, chúng tôi sử dụng cấu trúc mà chúng tôi gọi là cửa hàng cá thể. Cửa hàng này là một đối tượng được truy cập và sửa đổi hoàn toàn mỗi lần một hàm tạo cho một mô hình được gọi. Khi một mô hình được xây dựng lần đầu tiên, nó sẽ tự tiêm vào cửa hàng, sử dụng id của nó làm khóa duy nhất. Nếu cùng một hàm tạo mô hình được gọi với cùng một id, thì cá thể ban đầu được trả về.
var s1 = new Sound({id: 123}),
s2 = new Sound({id: 123});
s1 === s2; // true, these are the exact same object.
Điều này hoạt động vì tính năng ít được biết đến đáng ngạc nhiên của Javascript. Nếu một hàm tạo trả về một đối tượng, thì đó là giá trị được gán. Do đó, nếu chúng ta trả về một tham chiếu đến cá thể được tạo trước đó, chúng ta sẽ có được hành vi mong muốn. Đằng sau hậu trường, người xây dựng cơ bản thực hiện việc này:
var store = {};
function Sound(attributes) {
var id = attributes.id;
// check if this model has already been created
if (store[id]) {
// if yes, return that
return store[id];
}
// otherwise, store this instance
store[id] = this;
}
Tôi đã triển khai phiên bản này bằng cách ghi đè lớp Backbone.Model để tạo hàm tạo của riêng tôi.
var MyModel = Backbone.Model.extend({
constructor: function (attributes, options) {
var id = attributes ? attributes.id : undefined;
if (this.store[id]) {
return this.store[id];
}
Backbone.Model.prototype.constructor.apply(this, arguments);
if (id) {
this.store[id] = this;
}
}
});
var MyOtherModel = MyModel.extend({
store: {},
//other model stuff
});
Điều này hoạt động tốt, nhưng điều gì đó phải thay đổi và hiện đã ngừng hoạt động và tôi không chắc chắn lý do. Các cá thể mới tạo được lưu trữ trong đối tượng lưu trữ mà không có vấn đề - mỗi lớp mở rộng lớp MyModel có kho trống riêng của nó để tránh va chạm các cá thể của một kiểu khác với cùng một id. Ví dụ chính xác cũng được lấy ra mà không có vấn đề gì khi hàm tạo được gọi với một id hiện có, tuy nhiên khi chúng được trả về từ hàm khởi tạo, giá trị trả về bị bỏ qua. Sự hiểu biết của tôi từ spec là các nhà xây dựng có thể trả về một đối tượng - nhưng không phải là một nguyên thủy - và đối tượng trả về sẽ được gán cho bên trái của câu lệnh gán khi hàm tạo được gọi với toán tử mới. Điều này không xảy ra, mặc dù hàm khởi tạo trả về một đối tượng, đối tượng rỗng được tạo bởi toán tử mới được sử dụng.
Một số thông tin gỡ lỗi. Không chắc chắn thông tin này hữu ích như thế nào. Đây là "this" trong constructor MyModel cho một đối tượng được khởi tạo lần đầu tiên.
child
_callbacks: Object
_escapedAttributes: Object
_previousAttributes: Object
_setting: false
attributes: Object
id: "4fd6140032a6e522f10009ac"
manufacturer_id: "4f4135ae32a6e52a53000001"
name: "Tide"
uniqueName: "tide"
__proto__: Object
cid: "c50"
collection: child
id: "4fd6140032a6e522f10009ac"
__proto__: ctor
constructor: function(){ parent.apply(this, arguments); }
defaults: Object
store: Object
url: function() {
urlRoot: function() {
__proto__: ctor
Và đây là "này" trong constructor MyModel khi nó một đối tượng được trả lại từ các cửa hàng Ví dụ:
child
_callbacks: Object
_escapedAttributes: Object
_previousAttributes: Object
_setting: false
attributes: Object
_validate: function (attrs, options) {
bind: function (events, callback, context) {
change: function (options) {
changedAttributes: function (diff) {
clear: function (options) {
clone: function() {
constructor: function(){ parent.apply(this, arguments); }
defaults: Object
destroy: function (options) {
escape: function (attr) {
fetch: function (options) {
get: function (attr) {
has: function (attr) {
hasChanged: function (attr) {
idAttribute: "id"
initialize: function(){}
isNew: function() {
isValid: function() {
manufacturer_id: 0
name: ""
off: function (events, callback, context) {
on: function (events, callback, context) {
parse: function (resp, xhr) {
previous: function (attr) {
previousAttributes: function() {
save: function (key, value, options) {
set: function (key, value, options) {
store: Object
toJSON: function() {
trigger: function (events) {
unbind: function (events, callback, context) {
unset: function (attr, options) {
url: function() {
urlRoot: function() {
__proto__: Object
cid: "c141"
__proto__: ctor
constructor: function(){ parent.apply(this, arguments); }
defaults: Object
store: Object
url: function() {
urlRoot: function() {
__proto__: ctor
Những gì tôi lưu ý là các thuộc tính đối tượng trong một giây có tất cả các phương pháp của một đối tượng xương sống bao gồm trong đó, mà họ không nên. Nó cũng không có id, một lần nữa tôi không chắc tại sao. Hy vọng rằng điều này cung cấp một số cái nhìn sâu sắc. Cảm ơn.
Ông có thể cho chúng ta một deb ug view của MyModel? – Bergi
Chắc chắn. Xin lỗi vì sự thiếu hiểu biết của tôi nhưng bạn có thể chỉ định chính xác những gì bạn cần không? JavaScript gỡ lỗi người mới ở đây, gỡ lỗi của tôi thường bao gồm các câu lệnh console.log. – Kareem
Vâng, điều đó thật tuyệt. Tôi đoán nó là một chức năng, sau đó mã của nó và có thể là phạm vi biến nó có quyền truy cập vào sẽ là thú vị. – Bergi