2016-11-14 1 views
2

Действительно странная ошибка нокаута у меня есть. Это довольно сложный сценарий, поэтому, пожалуйста, эта скрипка:Нокаут, свойство коллекции становится null, когда я пытаюсь удалить один элемент из него, если в нем есть несколько элементов?

http://jsfiddle.net/yx8dkLnc/

По существу у меня есть двойная вложенная коллекция, первая коллекция FishMeasurements содержит коллекцию объектов, имеющие информацию видов, связанную с ним, а также коллекцией Measurements, которые содержат все измерения, связанные с этим видом.

Теперь, когда я пытаюсь и удалять элементы из вложенной коллекции в этом формате HTML: Функция измерения

<!-- ko foreach: FishMeasurements() --> 
       <h3><span data-bind="text: SpeciesName"></span><span data-bind="text: SpeciesId" style="display: none;"></span></h3> 
       <table class="table table-striped"> 
        <thead> 
         <tr> 
          <th>Length</th> 
          <th>Count</th> 
          <th>Weight</th> 
          <th>Fish Id</th> 
          <th>&nbsp;</th> 
         </tr> 
        </thead> 
        <tbody data-bind="foreach: Measurements()"> 
         <tr> 
          <td><span data-bind="text: LengthInMillimeters"></span></td> 
          <td><span data-bind="text: Count"></span></td> 
          <td><span data-bind="text: WeightInPounds"></span></td> 
          <td><span data-bind="text: FishCode"></span></td> 
          <td><a href="#" data-bind="click: function() { $root.removeMeasurement($data, $index); }">Remove</a></td> 
         </tr> 
        </tbody> 
       </table> 
      <!-- /ko --> 

Средство удаления не работает, когда Measurements коллекция имеет более одного объекта. Я нажимаю на ссылку удалить, и он выдает ошибку, которая говорит:

VM617:163 Uncaught TypeError: Cannot read property 'Measurements' of null(…)

Странная вещь об этом, если бы я только добавить один элемент в коллекцию измерения, удаления кнопки работают нормально, но как только я добавьте несколько измерений, если я нажму «удалить» на любом элементе таблицы, но в первой строке, эта ошибка будет сгенерирована. Однако, если я щелкнул первый элемент в таблице для каждого вида, нет ошибки, и все записи будут удалены!

Что-то говорит мне, что его лечебные измерения, как один объект, а не коллекции, потому что он работает только на индексе 0. Но я не уверен, потому что в консоли я могу набрать:

mappedModel.FishMeasurements()[0].Measurements()[1] 

И получить возвращается полный объект ko_mapping, поэтому он не равен нулю. Но по какой-то причине, когда я нажимаю кнопку «Удалить», он равен нулю. Пока существует только одно измерение для каждого вида, щелчок на удалении отлично работает, как только его больше ломается.

Что я делаю неправильно?

+0

Посмотрите на обновление на мой ответ. Надеюсь, что помогает –

ответ

1

Когда вы addMeasurement впервые speciesId, speciesName становятся определены, потому что fishMeasurementBySpecies === undefined и поэтому, когда вы удалите первый элемент у вас есть действительный measurement.SpeciesId() в качестве параметра внутри removeMeasurement функции, но во второй раз и больше, так как fishMeasurementBySpecies не undefined больше тогда speciesId, speciesName никогда не устанавливаются, а затем, когда вызывается removeMeasurement, measurement.SpeciesId() - null.

Для того, чтобы ваша модель работала, вам необходимо применить следующие изменения.

определяют var speciesId = mappedModel.SelectedSpecies(); перед вашим, если даного

var speciesId = mappedModel.SelectedSpecies(); 
if (fishMeasurementBySpecies === undefined || fishMeasurementBySpecies === null) { 

Помещенный () для Measurements внутри функции removeMeasurement, где вы хотите, чтобы получить длину

if(fishMeasurementBySpecies.Measurements().length === 0) 

Ниже я приведу вам пример того, что вы хотите сделать используя модель ручного просмотра вместо использования плагина mapping.


Пример: https://jsfiddle.net/kyr6w2x3/118/

Ваш пример: http://jsfiddle.net/yx8dkLnc/1/

VM:

var data = { 
    "AvailableSpecies": 
      [ 
      {"Id":"f57830b8-0766-4374-b481-82c04087415e","Name":"Alabama Shad"},  
      {"Id":"3787ce10-e61c-4f03-88a5-ff648bb55480","Name":"Alewife"},{"Id":"e923214f-4974-4663-9158-d6979ce637f1","Name":"All Sunfish Spp Ex Bass And Crappie"}   ], 
     "SelectedSpecies": null, "CountToAdd":0,"LengthToAdd":0,"WeightToAdd":0,"GenerateFishCode":false,"FishMeasurements":[] 
}; 
function AppViewModel(){ 
    var self = this; 
    self.AvailableSpecies = ko.observableArray(data.AvailableSpecies); 
    self.SelectedSpecies = ko.observable(); 
    self.CountToAdd = ko.observable(); 
    self.LengthToAdd = ko.observable(); 
    self.WeightToAdd = ko.observable(); 
    self.FishCode = ko.observable(); 
    self.FishMeasurements = ko.observableArray([]); 

    self.addMeasurement = function(item) { 
    var SpeciesExists = false; 

    ko.utils.arrayForEach(self.FishMeasurements(), function (item) { 
     if(item.SpeciesId() == self.SelectedSpecies().Id) { 
     var len = item.Measurements().length; 
     // you may have a better way to generate a unique Id if an item is removed 
     while(item.Measurements().findIndex(x => x.Id() === len) > 0){ 
      len++; 
     } 
     item.Measurements.push(new MeasurementsViewModel({LengthInMillimeters:self.LengthToAdd(), 
                  Count:self.CountToAdd(), 
                  WeightInPounds:self.WeightToAdd(), 
                  FishCode:self.FishCode(), 
                  Id:len ++, 
                  ParentId:self.SelectedSpecies().Id 
                  }) 
           ); 
     SpeciesExists = true; 
     } 
    }); 
    if(!SpeciesExists){ 
     self.FishMeasurements.push(new FishMeasurementsViewModel({SpeciesName:self.SelectedSpecies().Name, 
                   SpeciesId:self.SelectedSpecies().Id, 
                   Measurements:[{LengthInMillimeters:self.LengthToAdd(), 
                       Count:self.CountToAdd(), 
                       WeightInPounds:self.WeightToAdd(), 
                       FishCode:self.FishCode(), 
                       Id:1}] 
                   }) 
           ); 
    } 
    } 
    self.removeMeasurement = function(data){ 
     ko.utils.arrayForEach(self.FishMeasurements(), function (item) { 
      if(item && item.SpeciesId() == data.ParentId()) { 
      ko.utils.arrayForEach(item.Measurements(), function (subItem) { 
       if(subItem && subItem.Id() == data.Id()) { 
           item.Measurements.remove(subItem); 
       } 
      }); 
      } 
      if(item && item.Measurements().length == 0){ 
      self.FishMeasurements.remove(item); 
      } 
     }); 
    } 
} 
    var FishMeasurementsViewModel = function(data){ 
    var self = this; 
    self.SpeciesName = ko.observable(data.SpeciesName); 
    self.SpeciesId = ko.observable(data.SpeciesId); 
    self.Measurements = ko.observableArray($.map(data.Measurements, function (item) { 
    return new MeasurementsViewModel(item,self.SpeciesId()); 
    })); 

} 
var MeasurementsViewModel = function(data,parentId){ 
    var self = this; 
    self.LengthInMillimeters = ko.observable(data.LengthInMillimeters); 
    self.Count = ko.observable(data.Count); 
    self.WeightInPounds = ko.observable(data.WeightInPounds); 
    self.FishCode = ko.observable(data.FishCode); 
    self.Id = ko.observable(data.Id); 
    self.ParentId = ko.observable(parentId ? parentId : data.ParentId); 
} 

var viewModel = new AppViewModel(); 
ko.applyBindings(viewModel); 
+0

Удивительный, имеет смысл теперь, когда вы его нашли, было трудно заметить в моем беспорядке JS = /. – SventoryMang

+0

Да, моя ошибка, я просто поддержал это, ответ принял! – SventoryMang

Смежные вопросы