5

Có cách nào để định cấu hình một phần tử container thay vì lồng nội dung của nó bên trong phần tử vùng chứa Knockout component đến thay thế không.Thay thế phần tử vùng chứa khi sử dụng thành phần Knockout

Ví dụ, nếu tôi có một thành phần tùy chỉnh đăng ký như my-custom-element với mẫu sau:

<tr> 
    <p>Hello world!</p> 
</tr> 

Có thể sử dụng thành phần như thế này:

<table> 
    <tbody> 
     <my-custom-element></my-custom-element> 
    </tbody> 
</table> 

Và có sản phẩm cuối cùng là:

<table> 
    <tbody> 
     <tr> 
      <p>Hello world!</p> 
     </tr> 
    </tbody> 
</table> 

Thay vì điều này: (cách Knockout r Enders thành phần theo mặc định)

<table> 
    <tbody> 
     <my-custom-element> 
      <tr> 
       <p>Hello world!</p> 
      </tr> 
     </my-custom-element> 
    </tbody> 
</table> 

Based on the answer to this question, có vẻ như chức năng này được xây dựng vào cỗ máy template, mà tôi giả cũng được sử dụng khi vẽ mẫu thành phần.

Có cách nào để chỉ định rằng một thành phần sẽ được hiển thị bằng renderMode của replaceNode?

Tôi biết cú pháp "yếu tố ảo", cho phép các thành phần được định nghĩa bên trong một nhận xét HTML:

<table> 
    <tbody> 
     <!--ko component { name: 'my-custom-element' }--><!--/ko--> 
    </tbody> 
</table> 

nhưng tôi thực sự không thích cú pháp này - viết mã thực sự bên trong một bình luận cảm thấy như một bẩn, bẩn.

+1

Có vẻ như [Rendering một mẫu tên] (http://knockoutjs.com/documentation/template-binding.html) là những gì bạn đang tìm kiếm. Thành phần web, nói chung, một nút DOM, che khuất đó là trẻ em. Nó không có ý định _replaced_, vì bản thân khái niệm bị hủy hoại trong một trường hợp như vậy. – mudasobwa

Trả lời

4

Tôi tưởng tượng thiếu tùy chọn này có thể được bảo vệ như vậy, xem xét bản chất của thư viện (ở đó, tôi đã nói nó), và triết lý đội ngũ của nhà phát triển:

Knockout là một thư viện và không giống như khác MVC của nó không ép buộc bạn sử dụng một cách được định nghĩa khung để cấu trúc ứng dụng của bạn. Nếu bạn xem xét công cụ mẫu trong Knockout và hầu như tất cả các công cụ tạo khuôn mẫu JS khác (trong Góc cạnh, dấu gạch dưới, ria mép, v.v.), Knockout xuất hiện như là công cụ duy nhất không phải là "sửa đổi" HTML5 gốc. Tất cả những người khác sử dụng thẻ tùy chỉnh, có thể là <% %> hoặc {{ }} yêu cầu một trình phân tích cú pháp JS nhỏ để chuyển đổi thẻ thành một thứ có ý nghĩa (hiện tại KO cũng có một plugin Knockout punches bao gồm các thẻ kiểu ria mép. bit nhỏ với <!-- ko --> ý kiến). KO thay vào đó sử dụng HTML 5 các phần tử tùy chỉnh, thẻ nhận xét và thuộc tính, hoàn toàn "vanilla".

Ví dụ, loại JS/DOM của 'đối tượng (và cuộc sống thực?) Phân cấp' được sử dụng: chỉ cha mẹ có thể exerce quyền lực trên con mình, và do đó các yếu tố liên kết không được thay thế, nhưng mở rộng với trẻ em.Để minh hoạ:

// we cannot do this in JS 
document.getElementById('elem').remove(); //implied .remove(self) 
// instead we do this 
var elem = document.getElementById('elem'); 
container = elem.parentNode.removeChild(elem); 

Sau đó, cách ưa thích của liên kết dữ liệu với KO, minh họa tốt bởi các ràng buộc foreach, là:

<div data-bind="foreach: myList"> 
    <span data-bind="text: $data"></span> 
</div> 

Đoạn trước là một đại diện HTML của một JS mảng, cấu trúc phân cấp hiển thị lại:

var myArr = [1,2,3,4,5]; 
// we cannot do the following without reference to the array index, 
// which is not held by the object itself,  
// but a meta-property getting meaning relative to the parent 
myArr[0].splice(0,1); //remove 

Điều này dẫn đến chế độ xem HTML của bạn ct sao chép dữ liệu JS của bạn (và nó sẽ là thú vị để xem ai đó xây dựng một công cụ cho thấy các mức thụt lề liên kết dữ liệu (với withforeach) trong một tài liệu HTML. Tuy nhiên, trong một số trường hợp, bạn cần thẻ nhận xét để không làm lay chuyển HTML hoặc quy tắc css của bạn (lồng nhau), ví dụ thành phần 'chỉ văn bản' (i18n) được chèn giữa văn bản nút:

<p>Some predefined text with 
<!-- ko text: 'some variable text' --><!-- /ko --> 
and more predefined text</p> 

Hoặc khi bạn không muốn một phần tử rỗng để chiếm không gian khi ẩn

<!-- ko if: !hidden() --><div id="myToggleableDiv"></div><!-- /ko --> 

và sau đó có custom tags, đó là tiêu chuẩn và một địa ngục của rõ ràng hơn rất nhiều ; nhưng tiếc là chưa sẵn sàng 100%. Chọn data-bind trước tiên, <!-- ko --> giây và <custom> thứ ba (sẽ cao hơn nếu được triển khai đầy đủ). Đó là cách tôi nhìn thấy nó, anyway. Đối với trường hợp cụ thể của bạn, nếu thành phần của bạn giữ một mô hình danh sách, bạn có thể làm:

<table data-bind="{component: {name: 'custom', params {..}}"></table> 

Và bao gồm các tbody trong VM của bạn, nếu không nếu nó là một mô hình listitem, bạn có thể sử dụng một trong ba ' cú pháp, ví dụ như cú pháp bình luận

<table> 
    <tbody data-bind="foreach: mylist"> 
    <!-- ko component: {name: 'custom', params: $data} --><!-- /ko --> 
    </tbody> 
</table> 

Hoặc tách thành phần của bạn hoàn toàn từ các yêu cầu của bị lồng vào bên trong cha mẹ cụ thể (bảng), tôn trọng những SOC principle, ví dụ:

<table> 
    <tbody data-bind="foreach: mylist"> 
    <tr data-bind="foreach: properties"> 
     <td data-bind="component: {name: 'custom', params: $data}></td> 
    </tr> 
    </tbody> 
</table> 

hoặc với một thẻ tùy chỉnh:

<table> 
    <tbody data-bind="foreach: mylist"> 
    <tr data-bind="foreach: properties"> 
     <td><custom params= "{data: myData"></custom></td> 
    </tr> 
    </tbody> 
</table> 

trong thứ tự ưu tiên ..

2

Good News! Trong Knockout 3.3.0 họ vừa giới thiệu khái niệm về Passing markup into components. Điều này được thực hiện bằng cách sử dụng mẫu $componentTemplateNodes bên trong thành phần của bạn.

Từ ví dụ liên kết:

<template id="my-special-list-template"> 
    <h3>Here is a special list</h3> 

    <ul data-bind="foreach: { data: myItems, as: 'myItem' }"> 
     <li> 
      <h4>Here is another one of my special items</h4> 
      <!-- ko template: { nodes: $componentTemplateNodes, data: myItem } --><!-- /ko --> 
     </li> 
    </ul> 
</template> 

<my-special-list params="items: someArrayOfPeople"> 
    <!-- Look, I'm putting markup inside a custom element --> 
    The person <em data-bind="text: name"></em> 
    is <em data-bind="text: age"></em> years old. 
</my-special-list> 
Các vấn đề liên quan