10

Ứng dụng web của tôi có cấu trúc tổng hợp, nghĩa là mỗi bộ sưu tập Danh mục có thể chứa hỗn hợp các Mục riêng lẻ và Danh mục khác làm hàng/nút/trẻ em (không chắc chắn về thuật ngữ chính xác tại đây). Trong thực tế, nó đơn giản hơn một chút vì mỗi bộ sưu tập được đại diện bởi một mô hình, Category, do đó, về cơ bản, mỗi bộ sưu tập Category có cả hai mô hình Item và Category là con của nó.Triển khai mẫu tổng hợp bằng cách sử dụng MVC/Backbone.js

Nói chung đây là một cách được khuyến khích để thực hiện cấu trúc này bằng cách sử dụng MVC? Cụ thể hơn, trong Backbone.js là nó có thể cho một bộ sưu tập để có một nhà máy mô hình (lấy json và tính toán mô hình nào để tạo ra dựa trên cấu trúc của json) thay vì một thuộc tính mô hình tĩnh?

+0

Tóm lại, tôi muốn nói, "Tôi không hiểu tại sao không", nhưng tôi tò mò những gì người khác có thể nói. – JayC

Trả lời

1

Có, bạn có thể. Tôi đã hoàn thành nó trước đây. Tôi nghĩ rằng các liên kết này có thể giúp bạn: http://documentcloud.github.com/backbone/#Collection-model

Đây là một trong những kịch bản chính tôi sử dụng cho dự án của tôi: https://gist.github.com/b65893e0c2e3c46d3dc1

+0

Tôi thực sự không thể hiểu được bạn đã làm gì trong ý chính đó. Tất cả tôi có thể thấy là các mô hình của một loại, TransactionDetail, được thêm vào bộ sưu tập, wehn tôi muốn tự do thêm hai loại. Kể từ khi đăng câu hỏi này, tôi bắt đầu chỉnh sửa Backbone để thử và nhận được những gì tôi cần, nhưng nó có các quy tắc ID duy nhất sẵn có cho bộ sưu tập, vì vậy tôi nghĩ rằng tôi sẽ cần tạo một số mô hình cầu nối với id được tạo từ kiểu mô hình và id. Nhưng tôi vẫn quan tâm để xem nếu có một cách tốt hơn – wheresrhys

+0

Tôi thấy. Vâng, tôi hy vọng bạn có thể tìm cách để làm điều đó như bạn cần nó mặc dù. Tốt nhất của lucks. – MauroPorrasP

+0

Anh ấy đúng, bạn có thể cung cấp chức năng nhà máy làm thuộc tính mô hình của lớp Bộ sưu tập của bạn ... http://documentcloud.github.com/backbone/#Collection-model – inf3rno

5

Tôi giả sử bạn đang nhận được một danh sách loại/Các đề mục trong JSON trông giống như sau này ...

{ 
    'id': 1, 
    'name': 'My 1st Category', 
    'children': [ 
     { 
      'id': 2, 
      'name': 'My 2nd Category', 
      'children': [] 
     }, 
     { 
      'id': 1, 
      'name': 'An Item', 
      'price': 109.99 
     } 
    ] 
} 

Backbone.js không có bất kỳ thứ gì ngoài hộp hỗ trợ nhiều mô hình trong bộ sưu tập, nhưng cũng không có bất kỳ hạn chế nào về loại mô hình bạn đưa vào bộ sưu tập .

Chỉ định loại mô hình trong định nghĩa bộ sưu tập chỉ có một điều, nó cho phép Backbone biết loại mô hình nào sẽ tạo nếu bạn chuyển JSON thô vào bộ sưu tập thay vì đối tượng Backbone.Model. Nếu bạn thêm một mô hình Item vào một bộ sưu tập đã chứa một vài mô hình Category, xương sống sẽ không có vấn đề gì khi đưa nó vào danh sách mô hình; nó không làm bất kỳ kiểm tra kiểu nào.

Vì vậy, với ý nghĩ đó, bạn có thể sử dụng hầu hết mọi thứ mà bộ sưu tập cung cấp ngoại trừ truyền JSON thô; bạn sẽ cần phải tự mình xử lý. Vì vậy, lựa chọn của bạn là xây dựng mô hình của bạn trước, biến chúng thành các đối tượng Backbone.Model hoặc tạo một thứ gì đó sẽ thực hiện phân tích cú pháp cho bạn.

Đối với tùy chọn thứ hai, trình phân tích cú pháp, tôi khuyên bạn nên chuyển một biến đặc biệt cho bộ sưu tập chứa JSON thô của bạn, sau đó xử lý trong hàm initialize của bạn. Dưới đây là một ví dụ:

var CategoryCollection = Backbone.Collection.extend({ 
    initialize: function(m, models) { 
     _.each(models, function(model) { 
      var modelObject = null; 
      if (model.price !== undefined) { 
       modelObject = new Item(model); 
      } else { 
       modelObject = new Category(model); 
      } 

      this.add(modelObject); 
     }, this); 
    } 
}); 

Vì vậy, nó là một chút hacky, nhưng bạn xác định loại mô hình dựa trên nếu nó có một lĩnh vực cụ thể (price trong ví dụ của tôi), tạo ra các đối tượng mô hình, sau đó bổ sung vào bộ sưu tập.

Sau đó bạn muốn gọi nó theo cách này:

var myCollection = new CategoryCollection([], myJSON); 

Chú ý bạn phải vượt qua một mảng trống rỗng như là đối số đầu tiên kể từ đó là làm sao cậu thường thông qua một tập hợp các mô hình để bộ sưu tập.

Sau này khi sử dụng bộ sưu tập, bạn có thể xác định xem bạn đang làm việc với một Item hoặc Category sử dụng đơn giản instanceof kiểm tra:

_.each(myCollection.models, function(model) { 
    if (model instanceof Item) { 
     console.log("It's an Item! Price: ", model.get("price")); 
    } else { 
     console.log("It's a Category!"); 
    } 
}); 
+0

ý tưởng gọn gàng để sử dụng thông số tùy chọn để buôn lậu trong phần thô dữ liệu. – wheresrhys

+0

Haha cảm ơn. Tôi nghĩ rằng sẽ dễ dàng hơn là hack chính nguồn Backbone.js. Tôi đoán để làm sạch nó lên bạn luôn có thể tạo ra một lớp bao bọc mà bạn chỉ vượt qua JSON của bạn mà lần lượt tạo ra và trả về bộ sưu tập cho bạn. –

+0

Vâng, tôi muốn chiếm đoạt/quấn một vài phương pháp thu thập khác nữa, chủ yếu là nội bộ Backbone.Model hy vọng các id là duy nhất, ví dụ: tôi cần phải điều chỉnh id để chấp nhận một cặp khóa giá trị {modelType: id} hoặc bị giảm tương tự thành chuỗi được định dạng. – wheresrhys

1

Nó khá đơn giản đạt được bằng cách ghi đè được xây dựng trong các phương pháp công parsetoJSON được sử dụng nội bộ bằng xương sống khi truy xuất và lưu dữ liệu của mô hình.

Trước hết khi bạn lấy lại Mô hình từ cơ sở dữ liệu, bạn nên ghi đè phương thức parse của mô hình để tạo mô hình đại diện cho các mục nhất định từ ví dụ của bạn.

Sau đó, lưu phương thức toJSON được sử dụng để tuần tự hóa dữ liệu về máy chủ có thể hiểu - bạn chỉ cần gọi phương thức toJSON trên Mô hình của từng mục. Nếu bạn nhìn vào mã cho Backbone.sync, bạn sẽ thấy rằng mô hình luôn luôn được tuần tự hóa bằng cách sử dụng toJSON nếu không có dữ liệu tùy chỉnh nào được chuyển.

Hãy cho tôi biết nếu bạn cần thêm thông tin chi tiết mặc dù tôi tin rằng bạn sẽ có thể nhận thông tin từ đây!

+0

Tôi nghĩ rằng có thể tạo thành một phần của giải pháp, nhưng có những phương pháp khác có thể cần chỉnh sửa quá ví dụ Backbone.Collection._prepareModel (đối với ứng dụng của tôi, tôi chỉ có thể chắc chắn rằng tôi không bao giờ chuyển json thô đến Collection.add (mà các cuộc gọi. PrepareModel nội bộ), nhưng nó sẽ được tốt đẹp để có một giải pháp mà có thể xử lý bằng cách sử dụng Collection.add cho một loạt các jsons – wheresrhys

+0

Tôi tin rằng ghi đè phương pháp 'set' của mô hình để phân tích các thuộc tính/JSON thông qua có thể làm các trick - nó được gọi là khi mô hình được khởi tạo để thiết lập các thuộc tính được truyền mở rộng theo mặc định cả khi sử dụng 'Mô hình mới ({...})' và khi sử dụng 'collection.add ([{...}, ...])' –

+1

ps.chúng tôi đã học được một cách khó khăn mặc dù việc phát hành nhanh chóng xương sống 0,9 để sửa đổi các phương thức API riêng có thể phản tác dụng cho bạn :) đó là lý do tại sao tôi cố gắng tránh xa sự lộn xộn với '_prepareModel' nó sẽ không biến mất - nhưng ví dụ '_add' và' _remove' đã biến mất trong nhánh chính của xương sống –

1

Có, bạn có thể sử dụng mẫu Phương thức nhà máy để tạo mô hình trong Bộ sưu tập của xương sống. Giả sử các cấu trúc dữ liệu đề xuất trong @kpeel's answer, bạn có thể xác định

// Factory method 
var CategoryOrItemFactory = function(data, options) { 
    if (data.children) { 
     return new Category(data, options); 
    } else { 
     return new Item(data, options); 
    } 
}; 

// Model definitions 
var Item = Backbone.Model.extend(); 

var Category = Backbone.Model.extend({ 
    initialize: function() { 
     this.children = new Children(this.get("children")); 
    } 
}); 

var Children = Backbone.Collection.extend({ 
    model: CategoryOrItemFactory 
}); 

Sau đó bạn sẽ tạo mục gốc của bạn (loại) và có cấu trúc hoàn chỉnh dữ liệu được tạo ra:

// create the root item 
var rootItem = new Category(rawData); 

Tiếp cận một loại trẻ em tài sản children của nó , ví dụ

rootItem.children.get(2).get("name"); 

Đây là số jsFiddle with the above code để chơi cùng.

+0

Nhưng vẫn còn nhiều vấn đề khác nhau để đồng bộ với cơ sở dữ liệu và kỳ vọng Backbone.Collection của các id duy nhất (ví dụ: get không hoạt động đúng http: //jsfiddle.net/Z7Dbr/ - nó trả về kết quả phù hợp thứ hai và bỏ qua kết quả đầu tiên). Tôi nhận thấy trong ví dụ của bạn rằng Danh mục mở rộng mô hình hơn là Bộ sưu tập và tôi cũng không chắc chắn về mức độ thoải mái của mình với điều này, mặc dù để tránh phải làm các trình tái cấu trúc rộng rãi của backbone.js, tôi có thể phải tạo một số loại lai lớp học với một bộ sưu tập như một tài sản, thay vì kế thừa từ bộ sưu tập – wheresrhys

+0

Vâng, tôi đã cố gắng trả lời câu hỏi của bạn: liệu có thể có một nhà máy sản xuất mô hình (có) hay không. Danh mục của bạn phải có các thuộc tính (ví dụ: ID) để chúng cần được bắt nguồn từ Mô hình (ví dụ: 'Bộ sưu tập' của Bộ sưu tập thực hiện điều gì đó khác với phương thức của Mô hình). Giới thiệu về ID: làm cách nào để bạn xác định các mục nhập dữ liệu của mình ngay từ đầu? Tôi đoán nó sẽ có thể tạo ra một định danh có ý nghĩa và duy nhất khá dễ dàng? –

+0

Và đối với đồng bộ hóa: bạn có thể đặt giá trị 'url' chính xác cho cả Mục/Danh mục và Trẻ em. Làm cách nào để đồng bộ hóa dữ liệu của bạn? Bạn có thể cho chúng tôi thấy một số dữ liệu thực tế không? –

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