2012-01-09 25 views
7

Tôi đã đi qua một số tình huống mà tôi phải mã gọi mẫu của tôi như thế này:cú pháp mở rộng cho truyền thông số để KnockoutJS mẫu

<!-- ko template: {name: 'paginatedList', 
        data: {listContainer: paginatedResults, itemTemplate: $parent.template}} --> 
<!-- /ko --> 

vì ngoài đối tượng dữ liệu của tôi (ví dụ, paginatedResults), tôi cần truyền thông tin bổ sung như tên của mẫu để sử dụng trong các mục kết xuất. Ví dụ khác, khi hiển thị một mục trong danh sách, tôi có thể cần phải biết cài đặt hiện tại của bộ lọc được lưu trữ trong một số ngữ cảnh được xóa xa một cách hợp lý khỏi mục trong danh sách. Thay vì phải làm méo mô hình dữ liệu của tôi (trong ví dụ trên, thay thế paginatedResults bằng {listContainer: paginatedResults, itemTemplate: $parent.template}}, sẽ tốt hơn nếu có một chút cú pháp trên các mẫu cho phép tôi chuyển qua (và acccrue vì các mẫu được đánh giá theo thứ bậc) một số bối cảnh thêm rằng một mẫu sâu-lồng nhau có thể cần khi vẽ bản thân.

tôi đoán những gì tôi tự hỏi về là tính khả thi của việc thêm một thêm (không bắt buộc) tham số cho ko.bindingHandlers chức năng (initupdate) để làm cho chúng trông giống như này:

function (element, 
      valueAccessor, 
      allBindingsAccessor, 
      viewModel, 
      bindingContext, 
      context) 

Khi mã hóa ví dụ trên, tôi phải để có thể nói điều gì đó như

<!-- ko template: {name: 'paginatedList', 
        data: paginatedResults, 
        context: {itemTemplate: $parent.template}} --> 
<!-- /ko --> 

hoặc tốt hơn chưa,

<!-- ko template: {name: 'paginatedList', 
        data: paginatedResults, 
        itemTemplate: $parent.template} --> 
<!-- /ko --> 

và có itemTemplate trở thành một biến tôi có thể tham khảo trong các mẫu lồng nhau và data-bind thuộc tính.

Điều này có hợp lý không? Tôi không hiểu rõ về mức độ khó khăn của việc thực hiện này. Tôi đoán có một điều đáng lo ngại là va chạm tên, nhưng một số quy ước đặt tên có thể phá vỡ điều đó.

Gene

Trả lời

9

Nếu không có những thay đổi để KnockOut lõi, tôi nghĩ rằng tốt nhất mà bạn có thể làm là một wrapper ràng buộc tạo ra một cấu trúc tương tự như những gì bạn đang đi qua.

Binding có thể trông giống như:

ko.bindingHandlers.templateWithContext = { 
    init: ko.bindingHandlers.template.init, 
    update: function(element, valueAccessor, allBindings, data, context) { 
     var options = ko.utils.unwrapObservable(valueAccessor()); 

     ko.utils.extend(context, options.context); 

     return ko.bindingHandlers.template.update.apply(this, arguments); 
    } 
}; 

Bạn sẽ gọi nó là thích:

<div data-bind="templateWithContext: { name: 'itemsTmpl', data: items, context: { title: 'First' } }"></div> 

Đây là một mẫu: http://jsfiddle.net/rniemeyer/QNvFn/

Dường như bạn đang sử dụng mẫu tự nhiên, nhưng nếu bạn đang sử dụng mẫu jQuery vẫn còn, sau đó nó đã bao gồm một templateOptionsfeature sử dụng tính năng options của mẫu jQuery để chuyển dữ liệu ngữ cảnh. Điều này không có sẵn trong các mẫu gốc. Đề xuất chung bây giờ là sử dụng $root, $parent$parentsvariables để truy cập thông tin hoặc chuyển đối tượng dưới dạng data theo cách bạn mô tả trong bài đăng của mình.

+0

Cảm ơn! Tôi đồng ý rằng nó là loại điều đúng, nhưng không đủ để đảm bảo một trình xử lý ràng buộc thêm. Sẽ rất thú vị để xem tần suất mẫu này xuất hiện trong các ứng dụng phức tạp. –

+0

Cảm ơn nó giúp tôi rất nhiều.Nếu tôi viết một trình bao bọc mẫu, tôi có thể đặt tên mẫu bên trong 'init' không? – tbruyelle

+0

@tbruyelle - bạn chắc chắn có thể đặt tên. Ý tưởng sẽ được rằng bên trong wrapper của bạn ràng buộc bạn xây dựng các tùy chọn mà bạn muốn vượt qua để thực sự ràng buộc mẫu. Đây là một mẫu có thể chung chung hơn bạn cần (bạn chỉ có thể đặt tên trên đối tượng valueAccessor()): http://jsfiddle.net/rniemeyer/7rcFD/ –

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