2012-01-22 24 views
19

Hãy nói rằng chúng tôi có dữ liệu như sauProgressive Enhancement với KnockoutJS

var data = { 
    facets: [{ 
    name : "some name", 
    values: [{ 
     value: "some value" 
    }] 
    }] 
}; 

Chúng ta có thể dễ dàng thể hiện điều này như một mô hình điểm ràng buộc với một mẫu loại trực tiếp như sau:

<ul data-bind="foreach: facets">  
    <li>  
    <span data-bind="text: name"></span> 
    <ul data-bind="foreach: values">    
     <li data-bind="text: value"></li>  
    </ul> 
    </li> 
</ul> 

Câu hỏi đặt ra là, làm thế nào chúng ta có thể đạt được kết quả tương tự khi sử dụng nâng cao tiến bộ không? Đó là do có mẫu render trên phía máy chủ ban đầu và sau đó ràng buộc mẫu knockout và mô hình khung nhìn để render.

Một đơn giản mẫu phía máy chủ sẽ giống như thế này:

<ul>  
    <li>  
    <span>some name</span> 
    <ul>    
     <li>some value</li>  
    </ul> 
    </li> 
</ul> 

Tôi đã khám phá một vài khả năng khác nhau:

  • Một là tạo ra một mẫu loại trực tiếp và một bên mẫu máy chủ, và tạo mô hình khung nhìn Knockout động bằng cách phân tích cú pháp DOM cho mẫu phía máy chủ. Theo cách này, chỉ có mẫu Knockout sẽ hiển thị khi JavaScript được bật và chỉ mẫu bên phía máy chủ mới hiển thị nếu JavaScript bị tắt. Chúng có thể được tạo kiểu theo cách để làm cho chúng trông giống hệt nhau.

  • Cách tiếp cận khác là áp dụng các ràng buộc cho từng mục trong mảng facets một cách riêng biệt với phần tử DOM hiện có cho khía cạnh đó. Tuy nhiên, điều này vẫn chỉ có một cấp độ sâu và không hoạt động đối với các phần tử lồng nhau.

Không cách nào trong số các phương pháp này có vẻ khá sạch sẽ. Một giải pháp khác có thể là viết một ràng buộc tùy chỉnh xử lý toàn bộ hiển thị và sử dụng lại các phần tử hiện có nếu có thể.

Bất kỳ ý tưởng nào khác?

+0

Tôi đã từ bỏ tăng cường tiến bộ với Knockout. Ngoài bất cứ điều gì * siêu tầm thường * nó chỉ là không thực tế để giữ cho hành vi không KO/KO đồng bộ .. đây là một vấn đề với thậm chí tiêu chuẩn JavaScript PE, nhưng mô hình ràng buộc phong phú của KO làm cho nó một * phân cực cực * trong cách tiếp cận . (Có lẽ có một dự án "Phía máy chủ"? Điều đó sẽ là thú vị nếu nói ít nhất.) – user2864740

Trả lời

4

tôi khám phá nhiều cách tiếp cận ở đây, bao gồm cả việc tạo ra một mẫu vô danh từ phần tử đầu tiên, như mô tả ở đây:

http://groups.google.com/group/knockoutjs/browse_thread/thread/3896a640583763d7

hoặc tạo ra các ràng buộc riêng biệt cho mỗi phần tử của mảng thông qua một tùy chỉnh ràng buộc, chẳng hạn như

ko.bindingHandlers.prerenderedArray = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     var binding = valueAccessor();    
     binding.firstTime = true; 

     $(element).children().each(function(index, node) {     
      var value = ko.utils.unwrapObservable(binding.value)[index];       
      ko.applyBindings(value, node); 
     }); 

     return { 'controlsDescendantBindings': true };    
    }, 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {    
     var binding = valueAccessor(); 
     if (binding.firstTime) { 
      binding.firstTime = false; 
      return; 
     }    

     $(element).children().remove(); 
     ko.applyBindingsToNode(element, { template: { name: binding.template, foreach: binding.value }}, viewModel) 
    } 
};  

áp dụng một ràng buộc cụ thể cho từng phần tử và sau đó cập nhật lần đầu thay thế nội dung có gắn kết thông thường. Cách tiếp cận này vẫn có nghĩa là bạn vẫn cần phải có hai mẫu. Cả hai điều này cũng liên quan đến việc khởi tạo trạng thái thông qua một JSON được máy chủ trả về.

Cách tiếp cận hiện tại tôi đã chọn (vẫn có thể thay đổi) là đặt tất cả các mẫu Knockout bên trong các thẻ tập lệnh để chúng không bao giờ được hiển thị trong trình duyệt NoJS.Các mẫu NoJS được hiển thị dưới dạng nội dung của một div ở phía máy chủ. Ngay khi mẫu Knockout được hiển thị, nội dung của div sẽ được thay thế bằng mẫu Knockout trong thẻ script. Bạn có thể tạo kiểu cho chúng theo các cách giống hệt nhau/tương tự để làm cho quá trình chuyển đổi liền mạch và nếu điều này không thể ẩn mẫu noJS thông qua CSS. Cuối cùng, tôi đi đến kết luận rằng Knockout.js và nâng cao tiến bộ không thực sự làm việc tốt với nhau, người ta nên chọn một trong hai khác, tức là xây dựng một số phần của ứng dụng yêu cầu nâng cao tiến bộ bằng cách sử dụng truyền thống hơn các phương thức thao tác jQuery DOM trực tiếp như vậy.

+0

+1 Tôi đã đi đến kết luận tương tự - không có hỗ trợ đầy đủ phía máy chủ cho KO (một dự án mới, bất cứ ai?), nó chỉ là quá phân biệt phương pháp tiếp cận từ mô hình HTML/postback truyền thống để thực tế được đồng bộ hóa. – user2864740

3

Chỉ cần thêm các thuộc tính khác nhau data- vào mẫu phía máy chủ. Họ không làm tổn thương nếu JavaScript bị vô hiệu hóa, vì vậy họ không phải là vấn đề gì cả.

+3

Điều đó chỉ hoạt động nếu bạn có cấu trúc dữ liệu phẳng, làm cách nào bạn xử lý mảng và mảng lồng nhau? –

+0

Vâng, cũng thêm và loại bỏ các dòng từ bảng, đó là loại điều. –

3

Tôi e rằng không có cách nào để làm điều đó một cách rõ ràng. Cá nhân tôi làm cho trang trong backend và sau đó tôi chuyển dữ liệu ngữ cảnh rất giống với frontend (serialized như JSON) và thiết lập Knockout bằng cách sử dụng nó. Điều này có nghĩa là có một số trùng lặp. Có lẽ việc chuyển backend sang node.js sẽ đơn giản hóa mọi thứ ở đây.

+1

Tôi khá nhiều đến cùng một kết luận, thật không may. Có lẽ nó sẽ được cải thiện trong một phiên bản tương lai của Knockout (tức là thông qua một số cách để liên kết với các phần tử dom hiện có). –

+0

Tomasz, tò mò làm thế nào bạn làm cho phía máy chủ - bạn đang sử dụng nút? tê giác? thứ gì khác? Nói chung, tò mò nếu bạn đã quản lý để sử dụng cùng một phía máy chủ mẫu như trên máy khách, hoặc nếu bạn phải duy trì hai bộ mẫu. –

+0

@Karl: Phần phụ trợ là Django, vì vậy các mẫu trông giống như sau:

{{ my_data }}

0

here, tôi đã đề xuất mẫu liên kết sử dụng HTML được tạo từ máy chủ. Nó sử dụng tôi tương tự như bản gốc ràng buộc mẫu, ngoại trừ vài dữ liệu thuộc tính sẽ được sử dụng bởi các ràng buộc.

+0

Nếu sử dụng * bất kỳ * KO, tại sao không sử dụng tất cả KO? Có KO làm việc trên chỉ là một phần khá nhiều phá vỡ hầu hết các tình huống PE (không có gì tôi làm việc trên đó là tầm thường đủ KO có thể được trivially loại bỏ và duy trì chức năng). – user2864740

0

Tăng cường nâng cao dễ dàng hơn nhiều với dữ liệu không lặp như biểu mẫu (như tôi đã viết ở đây: http://www.tysoncadenhead.com/blog/using-knockout-for-progressive-enhancement). Cá nhân, tôi nghĩ rằng looping trên nhiều mục trong DOM và tái rendering chúng có vẻ như nó sẽ là một thực hiện khó khăn, nhưng thật khó để nghĩ về bất cứ điều gì tốt hơn.

+0

Dưới đây là ví dụ về cách bạn có thể lặp qua một loạt các mục trên máy chủ và sau đó vẽ lại chúng trong vòng lặp Knockout foreach: http://www.tysoncadenhead.com/blog/using-knockout-for-progressive- danh sách nâng cao –

1

Đây là của tôi về nó, ví dụ cơ bản này sử dụng một ràng buộc tùy chỉnh để tải các giá trị phía máy chủ vào mô hình xem.

Progressive Enhancement with KnockoutJS Infinite Scroll

screenshot

tăng cường Progressive ràng buộc

ko.bindingHandlers.PE = { 
    init: function(element, valueAccessor, allBindings) { 
     var bindings = allBindings(); 
     if (typeof bindings.text === 'function') { 
      bindings.text($(element).text()); 
     } 
    } 
}; 
Các vấn đề liên quan