2015-02-03 4 views
0

У меня есть Datatable, который принимает данные из массива Knockout ViewModel. Новые строки добавляются отлично, когда я нажимаю новые объекты в массив, но когда объект в этом массиве изменяется, строка не обновляется.Обновление jquery DataTable при изменении нокаута ViewModel

Код relecent ViewModel:

..... 
    self.Products = ko.observableArray(); 
    ..... 

Выборочные данные (например результат ko.toJSON (VM.Products())):

"[ 
    {"Price":"114.28","Name":"Pearls","Description":"Little and big","Quantity":3}, 
    {"Price":"117.55","Name":"Silver","Description":"Sliver Coins","Quantity":2}, 
    {"Price":"166.09","Name":"Phone","Description":"Nokia","Quantity":2}, 
    {"Price":"169.36","Name":"Wood","Description":"Northen forest wood","Quantity":1} 
    ]" 

Тогда Datatable код:

var CartDt = $("#PurchasedPrdTbl").DataTable({   
    pageLength: 5,  
    aoData: ko.toJSON(VM.Products()), 
    columns: [ 
     { "title": 'Price' }, 
     { "title": 'Name' }, 
     { "title": 'Description' }, 
     { "title": 'Quantity' }, 
     { 
      "className": 'remove-details-control', 
      "orderable": false, 
      "data": null, 
      "defaultContent": '', 
      "title": "Sell Me!", 
      "fnRender": function (oObj) { 

       return oObj.aData; 
      } 
     } 
    ] 
}); 

I'v попробовал ajax.reload, но это не помогло.

Любые идеи были бы замечательными, спасибо.

EDIT:

Я пытаюсь fnUpdate (source), как это:

CartDt.fnUpdate([{"Price":"114.28","Name":"Pearls","Description":"Little and big","Quantity":3}],1); 

Но я получаю это: неперехваченный TypeError: неопределенный не является функция

+0

хорошо вы связывании JSON для данных-таблицы (требуется). Если вы измените их, они не изменятся, потому что нет прав на наблюдаемые. –

+0

@spuer классный, но JSON IS наблюдаемый - self.Products = ko.observableArray(); –

+1

Не в восторге. вам нужно использовать 'arrayMap' или плагин для преобразования данных JSON в наблюдаемые и вставить его в' self.Products'. просто присваивание данных JSON наблюдаемому массиву не означает, что все внутри видимо. –

ответ

0

Это происходит потому, html, связанный с вашим наблюдаемым массивом с нокаутом, искажается при инициализации datatables ... html копируется и переформатируется как «datatables» после инициализации. поэтому элементы, которые вы просматриваете после инициализации datatables, не являются теми же элементами, с которыми связан нокаутом. Я создал пользовательскую привязку для использования datatables с нокаутом. он зависит от вилки нокаута, который добавляет перед рендером все и после рендеринга всех событий. Я создал запрос на перенос с репозиторием git-хаба нокаута. Если приведенное ниже решение поможет вам, пожалуйста, оставьте комментарий к запросу на тяну, чтобы он слился в нокаут 3.4 ... спасибо.

fiddle of working solution

my pull request

ko.bindingHandlers.DataTablesForEach = { 

     init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
      var nodes = Array.prototype.slice.call(element.childNodes, 0); 
      ko.utils.arrayForEach(nodes, function (node) { 
       if (node && node.nodeType !== 1) { 
        node.parentNode.removeChild(node); 
       } 
      }); 
      return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
     }, 
     update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 

      var value = ko.unwrap(valueAccessor()), 
      key = "DataTablesForEach_Initialized"; 

      var newValue = function() { 
       return { 
        data: value.data || value, 
        beforeRenderAll: function (el, index, data) { 

         if (ko.utils.domData.get(element, key)) { 
          $(element).closest('table').DataTable().clear(); 
          $(element).closest('table').DataTable().destroy(); 
         } 
        }, 
        afterRenderAll: function (el, index, data) { 
         $(element).closest('table').DataTable(value.options); 
        } 

       }; 
      }; 

      ko.bindingHandlers.foreach.update(element, newValue, allBindingsAccessor, viewModel, bindingContext); 

      //if we have not previously marked this as initialized and there is currently items in the array, then cache on the element that it has been initialized 
      if (!ko.utils.domData.get(element, key) && (value.data || value.length)) { 
       ko.utils.domData.set(element, key, true); 
      } 

      return { controlsDescendantBindings: true }; 
     } 
    }; 
Смежные вопросы