нокаут привязывает отношение «один ко многим» к себе (рекурсия в нокауте)

Итак, в моей базе данных у меня есть модель, которая имеет отношения один ко многим сама с собой. Хорошим примером этого является система комментариев, как на Reddit.

В настоящее время я делаю что-то вроде этого:

<div class="body" data-bind="foreach: { data: Comments}">
    <span data-bind="text: '(' + OrderQualifier + ') ' + Text"></span>
    <!-- ko foreach: { data: Children } -->
        <span data-bind="text: '(' + OrderQualifier + ') ' + Text"></span> 
    <!-- /ko -->
</div>

который, очевидно, поддерживает только один уровень детей. Есть ли чистый способ структурировать это, когда Child (Children[i]) может иметь или не иметь массив Children, который необходимо зациклить. В моем примере технически может быть бесконечное количество таких уровней (но этого не будет).

Я почти уверен, что мог бы придумать что-то хакерское, но я думаю, что может быть лучший способ. Спасибо.

Редактировать:

Данные, которые я хотел бы отобразить:

{  
   "@odata.context":"http://localhost:3080/odata/$metadata#SectionApi(*)/$entity",
   "SectionID":4,
   "Text":"Text",
   "Html":null,
   "OrderQualifier":"1",
   "IsUserCreated":false,
   "Children":[  
      {  
         "@odata.context":"http://localhost:3080/odata/$metadata#SectionApi(*)/$entity",
         "SectionID":4,
         "Text":"Text",
         "Html":null,
         "OrderQualifier":"1",
         "IsUserCreated":false,
         "Children":[  
            {  
               "@odata.context":"http://localhost:3080/odata/$metadata#SectionApi(*)/$entity",
               "SectionID":4,
               "Text":"Text",
               "Html":null,
               "OrderQualifier":"1",
               "IsUserCreated":false,
               "Children":[  
                  {  
                     "@odata.context":"http://localhost:3080/odata/$metadata#SectionApi(*)/$entity",
                     "SectionID":4,
                     "Text":"Text",
                     "Html":null,
                     "OrderQualifier":"1",
                     "IsUserCreated":false,
                     "Children":[  

                     ]
                  }
               ]
            }
         ]
      }
   ]
}

Как вы можете видеть, это содержит 3 уровня дочерних комментариев, но мне нужно иметь возможность обрабатывать неизвестное количество дочерних комментариев.


person chris stevens    schedule 09.08.2014    source источник
comment
хорошо, если вы опубликуете некоторые образцы данных, было бы хорошо пройти   -  person Muhammad Raheel    schedule 09.08.2014


Ответы (2)


шаблон нокаута поддерживает рекурсию. http://jsfiddle.net/m812qjeq/2/

<div class="body" data-bind="foreach: Comments">
    <div data-bind="template: { name: 'childTemplate', data: $data }"></div>
</div>

<script type="text/html" id="childTemplate">
    <span data-bind="text: '(' + OrderQualifier + ') ' + Text"></span>
    <!-- ko if: $data.Children -->
        <!-- ko foreach: Children -->
            <div data-bind="template: { name: 'childTemplate', data: $data }"></div>
        <!-- /ko -->
    <!-- /ko -->
</script>
person huocp    schedule 09.08.2014
comment
это именно то, что я собирался сделать - person Muhammad Raheel; 09.08.2014

Вы можете использовать шаблон для этого

<div class="body" data-bind="foreach: comments">
    <div data-bind="template: { name: 'childTemplate', data: $data }"></div>
</div>

<script type="text/html" id="childTemplate">
    <span data-bind="text:comment"></span>
    <!-- ko if: $data.childrenLength > 0 -->
        <!-- ko foreach: children -->
            <div data-bind="template: { name: 'childTemplate', data: $data }" style="padding-left:35px;"></div>
        <!-- /ko -->
    <!-- /ko -->
</script>

пример модели представления

var comments = [{
    id: 1,
    comment: 'How can i use knockoutjs?',
    childrenLength: 3,
    children: [{
        id: 2,
        comment: 'Please seach before asking',
        childrenLength: 0,
        children: []
    }, {
        id: 3,
        comment: 'Please read the documentation',
        childrenLength: 0,
        children: []
    }, {
        id: 4,
        comment: 'You can see the blog posts on this',
        childrenLength: 2,
        children: [{
            id: 5,
            comment: 'Please seach before asking',
            childrenLength: 0,
            children: []
        }, {
            id: 6,
            comment: 'Please seach before asking',
            childrenLength: 0,
            children: []
        }]
    }]
}, {
    id: 7,
    comment: 'You question is not sufficient to be asked here?',
    childrenLength: 3,
    children: [{
        id: 8,
        comment: 'Please seach before asking',
        childrenLength: 0,
        children: []
    }, {
        id: 9,
        comment: 'Please read the documentation',
        childrenLength: 0,
        children: []
    }, {
        id: 10,
        comment: 'You can see the blog posts on this',
        childrenLength: 0,
        children: []
    }]
}]

var vm = function(){
    var self = this
    self.comments = ko.observableArray(comments)
}

$('document').ready(function () {
    ko.applyBindings(new vm())
})

Демонстрация скрипки

person Muhammad Raheel    schedule 09.08.2014