2013-07-03 3 views
0
обновленного

Я пытаюсь добавить новые объекты в моем нокаута отображения плагин dowloaded ViewModel, например, так:Несогласованность между отображением Нокаут плагина извлекаются объекты ViewModel и те

<script type="text/javascript"> 
    var myViewModel = {}; 

    var Fighter = function (data) { 
     var self = this; 
     self.Name = ko.observable(data.Name); 
     self.Country = ko.observable(data.Country); 
     self.TopSpeed = ko.observable(data.TopSpeed); 
    }; 

    var WarCraft = function (data) { 
     var self = this; 
     self.fighter = ko.observable(data.fighter); 
    }; 

    var dataMappingOptions = { 
     key: function (data) { 
      return data.id; 
     }, 
     create: function (options) { 
      if (data.id == 1) 
       return new Fighter(options.data); 
      else 
       if (data.id == 2) 
        return new WarCraft(options.data); 
     } 
    }; 

    $.getJSON("/Home/GetServerData", function (model) { 
     ko.mapping.fromJS(model, dataMappingOptions, myViewModel); 

     ko.applyBindings(myViewModel); 

    }).error(function() { alert("Oops!") }).success(function() { alert("Yeah!") }); 


    myViewModel.AddToData = function() { 
     var newFighter = new Fighter(
         { 
          id : 1, 
          Name: myViewModel.warCraft.fighter.Name(), 
          Country: myViewModel.warCraft.fighter.Country(), 
          TopSpeed: myViewModel.warCraft.fighter.TopSpeed() 
         }); 
     var newWarCraft = new WarCraft({ id: 2, fighter: newFighter }); 
     myViewModel.WW2Machines.push(newWarCraft); 
    }.bind(myViewModel); 


</script> 

Серверный модель:

DataModel model = new DataModel(); 
model.warCraft = new WarCraft(); 
model.warCraft.fighter = new Fighter(); 
model.warCraft.fighter.Name = "Spitfire"; 
model.WW2Machines = new List<WarCraft>(); 

WarCraft w1 = new WarCraft(); 
w1.fighter = new Fighter() { Name = "Spitfire" }; 
model.WW2Machines.Add(w1); 

WarCraft w2 = new WarCraft(); 
w2.fighter = new Fighter() { Name = "Hurricane" }; 
model.WW2Machines.Add(w2); 

WarCraft w3 = new WarCraft(); 
w3.fighter = new Fighter() { Name = "Tomcat" }; 
model.WW2Machines.Add(w3); 

... метод вызывается при вызове Ajax, который инициализирует и отправляет данные:

DataModel model = new DataModel(); 
model.warCraft = new WarCraft(); 
model.warCraft.fighter = new Fighter(); 
model.warCraft.fighter.Name = "Spitfire"; 
model.WW2Machines = new List<WarCraft>(); 

WarCraft w1 = new WarCraft(); 
w1.fighter = new Fighter() { Name = "Spitfire" }; 
model.WW2Machines.Add(w1); 

WarCraft w2 = new WarCraft(); 
w2.fighter = new Fighter() { Name = "Hurricane" }; 
model.WW2Machines.Add(w2); 

WarCraft w3 = new WarCraft(); 
w3.fighter = new Fighter() { Name = "Tomcat" }; 
model.WW2Machines.Add(w3); 

return Json(model, JsonRequestBehavior.AllowGet); 

. , , и мой HTML:

<div id="show" data-bind="visible: WW2Machines().length>0"> 
    <h2>Information Display:</h2> 
    NewNumber : <span data-bind="text: WW2Machines().length"></span> 
    <ul data-bind="foreach: WW2Machines"> 
     <li> 
      Name: <span data-bind="text: fighter.Name"></span> 
      <br>&nbsp;</br> 
     </li> 
    </ul> 
</div> 

<div id="theForm"> 
    @using (Html.BeginForm()) 
    { 
     <legend WW2 Fighter Planes: > 
      <fieldset> 
       Name: 
       <br>&nbsp;</br> 
       <select data-bind="value: warCraft.fighter.Name, optionsCaption: 'Please Select . . '"> 
        <option>Mosquito</option> 
        <option>Mustang</option> 
        <option>Messerschmidt 109</option> 
       </select> 
       <br>&nbsp;</br> 
       <span data-bind="text: warCraft.fighter.Name"></span> 
       <br>&nbsp;</br> 

       Country: 
       <br>&nbsp;</br> 
       <select data-bind="value: warCraft.fighter.Country, optionsCaption: 'Please Select . . '"> 
        <option>England</option> 
        <option>USA</option> 
        <option>Germany</option> 
       </select> 
       <br>&nbsp;</br> 
       <span data-bind="text: warCraft.fighter.Country"></span> 
       <br>&nbsp;</br> 

       Top Speed: 
       <br>&nbsp;</br> 
       <select data-bind="value: warCraft.fighter.TopSpeed, optionsCaption: 'Please Select . . '"> 
        <option>390 km/h</option> 
        <option>275 km/h</option> 
        <option>250 km/h</option> 
       </select> 
       <br>&nbsp;</br> 
       <span data-bind="text: warCraft.fighter.TopSpeed"></span>     

       <input type="button" data-bind="click: AddToData">Add</input> 

      </fieldset> 

     </legend> 

} 

Проблема заключается в том, что моя кнопка Add запускается и не добавлять строки в область дисплея, за исключением того, что они пусты. В консоли отладчика в Firefox я вижу, что я могу ссылаться как на строки, отправленные с сервера, так и на строки, добавленные кнопкой «Добавить» (содержащие данные правильно) с одной загадочной разницей: Я получаю существующие строки с этим синтаксисом:

myViewModel.WW2Machines() [0] .fighter.Name()

. , , и мои Добавленные строки с этим синтаксисом:.

myViewModel.WW2Machines() [3] .fighter() Название()

. , , и синтаксис swopping между собой для соответствующих индексов вызывает ошибку. Это может быть ключом к тому, почему мои строки добавляются как пробелы, но я не знаю, почему? Может ли кто-нибудь помочь, пожалуйста?

+0

Я хотел бы знать, как плагин отображения решает, что делать, и что не делать. Разве ВСЕ объекты и составляющие дочерние объекты не должны были наблюдаться с помощью плагина сопоставления? Еще раз спасибо. – user1457664

ответ

0

По крайней мере, некоторые из проблем и объяснение загадочной разницы, с которой вы сталкиваетесь внизу, состоят в том, что строки, которые вы добавляете позже, делают WarCraft.fighter наблюдаемым, что плагин отображения не делает.

Таким образом, вы могли бы обменять это:

var WarCraft = function (data) { 
    var self = this; 
    self.fighter = ko.observable(data.fighter); 
}; 

для этого

var WarCraft = function (data) { 
    var self = this; 
    self.fighter = data.fighter; 
}; 

, и вы должны быть в состоянии получить доступ к обоим отображенные данные и добавленные данные таким же образом:

myViewModel.WW2Machines()[0].fighter.Name() 
+0

Отлично! Спасибо! :) :) :) – user1457664

0

Adrien, можете ли вы предложить объяснение, почему плагин отображения не делает WarCraft.fighter наблюдаемым? Я думал, что все объекты и под-свойства отображаются с использованием плагина по умолчанию для наблюдаемого. Спасибо,

+0

На самом деле это не ответ на вопрос. Вы должны опубликовать это как комментарий к принятому ответу вместо этого. – BenR

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