2016-06-04 3 views
0

У меня есть наблюдаемый массив для списка флажков, и я обрабатываю проверочное событие с помощью наблюдаемого массива.Наблюдаемые изменения массива не отражают первый щелчок - KnockoutJS

Теперь, когда я делаю изменения, значения массива обновляются мгновенно, но это не отражается на DOM. но когда я нажимаю на какой-то другой элемент, это отражает изменение.

Короче говоря, изменение значений массива не отражается при первом щелчке, но при втором нажатии это делает.

Вот мой код:

 /*--- Factory Objects ---*/ 
    var ModelFactory = function() { 
     this.ModelTitle = ko.observable(); 
     this.ModelId = ko.observable(); 
     this.FamilyId = ko.observable(); 
    } 
    var SeriesFactory = function (SeriesTitle, SeriesId) { 
     this.SeriesTitle = ko.observable(); 
     this.SeriesId = ko.observable(); 
    }; 
    var OptionsFactory = function (SelectionFlag, OptionTitle, OptionId, OptionPrice, OptionType, ModelId) { 
     var self = this; 
     this.OptionTitle = ko.observable(); 
     this.OptionId = ko.observable(); 
     this.OptionType = ko.observable(); 
     this.OptionPrice = ko.observable(); 
     this.ModelId = ko.observable(); 
     this.SelectionFlag = ko.computed(function() { 
      return self.OptionType() === "0" ? self.OptionId() : null; 
     }); 
     this.FormattedOptionPrice = ko.computed(function() { 
      return "USD " + self.OptionPrice(); 
     }); 
    }; 
    /*--- Factory Objects End ---*/ 
    /*--- ViewModel ----*/ 
    function OpportunityViewModel() { 
     var self = this; 
     self.SeriesList = ko.observableArray([]); 
     self.ModelList = ko.observableArray([]); 
     self.OptionList = ko.observableArray([]); 
     self.SelectedOptionsList = ko.observableArray([]); 
     self.LoadSeries = function() { 
      self.ClearFactory(self.SeriesList); 
      for (var i = 0; i < familyList.length; i++) { 
       self.SeriesList.push(new SeriesFactory().SeriesId(familyList[i].Id).SeriesTitle(familyList[i].FamilyTitle)); 
      } 
     }; 
     self.LoadModels = function (seriesId) { 
      self.ClearFactory(self.ModelList); 
      for (var i = 0; i < productList.length; i++) { 
       if (seriesId() === productList[i].FamilyId) { 
        self.ModelList.push(new ModelFactory().ModelId(productList[i].Id).ModelTitle(productList[i].ModelTitle).FamilyId(productList[i].FamilyId)); 
       } 
      } 
     }; 
     self.SeriesClick = function (seriesObject, event) { 
      if (seriesObject !== null && typeof seriesObject !== 'undefined') { 
       self.LoadModels(seriesObject.SeriesId); 
      } 
     }; 
     self.ModelClick = function (modelObject, event) { 
      if (modelObject !== null && typeof modelObject !== 'undefined') { 
       self.LoadOptions(modelObject.ModelId); 
      } 
     }; 
     self.LoadOptions = function (modelId) { 
      self.ClearFactory(self.OptionList); 
      for (var i = 0; i < optionList.length; i++) { 
       if (modelId() === optionList[i].ModelId) { 
        self.OptionList.push(new OptionsFactory() 
         .OptionId(optionList[i].Id) 
         .OptionTitle(optionList[i].OptionTitle) 
         .OptionPrice(optionList[i].OptionPrice) 
         .OptionType(optionList[i].OptionType) 
         .ModelId(optionList[i].ModelId) 
         ); 
        if (optionList[i].OptionType === "0") { 
         self.SelectedOptionsList.push(optionList[i].Id); 
        } 
       } 
      } 
     }; 
     self.SelectedOptions = function (selectedItem) { 
      console.clear(); 
      for (var i = 0; i < self.SelectedOptionsList().length; i++) { 
       if (self.SelectedOptionsList()[i] === selectedItem.OptionId()) { 
        self.SelectedOptionsList.remove(selectedItem.OptionId()); 
        console.log(JSON.stringify(self.SelectedOptionsList())); 
        return; 
       } 
      } 
      self.SelectedOptionsList.push(selectedItem.OptionId()); 
      console.log(JSON.stringify(self.SelectedOptionsList())); 
     }; 
     self.ClearFactory = function (observableFactory) { 
      observableFactory([]); 
     }; 
    } 
    /*--- View Model End ---*/ 
    /*--- Init --- */ 
    $(function() { 
     var opportunityVM = new OpportunityViewModel(); 
     opportunityVM.LoadSeries(); 
     ko.applyBindings(opportunityVM); 
    }); 
    /*--- Init End ---*/ 

и шаблон

<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#productSearch"> 
    Launch Modal 
</button> 
<div class="modal fade" id="productSearch" role="dialog" aria-labelledby="productDialogTitle"> 
    <div class="modal-dialog modal-lg" role="document"> 
     <div class="modal-content"> 
      <div class="modal-header"> 
       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> 
       <h4 class="modal-title" id="productDialogTitle">Product Selection</h4> 
      </div> 
      <div class="modal-body"> 
       <div class="row"> 
        <div class="col-md-4"> 
         <div class="panel panel-primary"> 
          <div class="panel-heading"> 
           <h3 class="panel-title">Series Selection</h3> 
          </div> 
          <div class="panel-body"> 
           <ul data-bind="foreach: SeriesList" id="ulFamilyList"> 
            <li><a class="btn btn-link series" data-bind="text: SeriesTitle, attr: {Id: SeriesId}, click: $parent.SeriesClick"></a></li> 
           </ul> 
          </div> 
          <div class="panel-footer"> 

          </div> 
         </div> 
        </div> 
        <div class="col-md-4"> 
         <div class="panel panel-primary"> 
          <div class="panel-heading"> 
           <h3 class="panel-title">Model Selection</h3> 
          </div> 
          <div class="panel-body"> 
           <ul id="ulModelList" data-bind="foreach: ModelList"> 
            <li><a class="btn btn-link productModel" data-bind="text: ModelTitle, attr:{Id: ModelId}, click: $parent.ModelClick"></a></li> 
           </ul> 
          </div> 
          <div class="panel-footer"> 

          </div> 
         </div> 
        </div> 
        <div class="col-md-4"> 
         <div class="panel panel-primary"> 
          <div class="panel-heading"> 
           <h3 class="panel-title">Option Selection</h3> 
          </div> 
          <div class="panel-body"> 
           <table class="table table-stripped table-hover table-bordered" id="ulOptionList" data-bind="foreach: OptionList"> 
            <tr class="optionListRow"> 
             <td> 
              <input type="checkbox" data-bind="value: OptionId, click: $parent.SelectedOptions, checked: $parent.SelectedOptionsList" /> 
              <span data-bind="text: '&nbsp' + OptionTitle()"></span> 
             </td> 
             <td> 
              <p data-bind="text: FormattedOptionPrice"></p> 
             </td> 
            </tr> 
           </table> 
          </div> 
          <div class="panel-footer"> 

          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
      <div class="modal-footer"> 
       <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 
       <button type="button" class="btn btn-primary">Save changes</button> 
      </div> 
     </div> 
    </div> 
</div> 

Что я делаю неправильно? Также я просто еще один новобранец и только что начал работу с KnockoutJS. Я был бы признателен, если бы специалисты здесь также оптимизировали этот код и продемонстрировали некоторые из его навыков, улучшающих его.

Спасибо :)

UPDATE

Вот некоторые тестовые данные, которые я использую.

 familyList = [ 
     { FamilyTitle: "3 Series", Id: "9e55c0ae-37d0-0d89-808f-acccfb58562f" }, 
     { FamilyTitle: "5 Series", Id: "3d9d6640-a8b5-b4ed-56d2-ef9d1d6f8544" }, 
     { FamilyTitle: "7 Series", Id: "c395c655-f302-852a-ccca-1a5e9bf10e0e" }, 
     { FamilyTitle: "X Series", Id: "3e31300f-1dcb-1d50-f796-c58c76cb4ab2" } 
    ]; 
    productList = [ 
     { ModelTitle: "325i", Id: "e1d17dbf-3142-4bde-89bd-830caa09eb93", FamilyId: "9e55c0ae-37d0-0d89-808f-acccfb58562f" }, 
     { ModelTitle: "525i", Id: "9ac7da72-5224-6046-3913-c2700c486682", FamilyId: "3d9d6640-a8b5-b4ed-56d2-ef9d1d6f8544" }, 
     { ModelTitle: "X5", Id: "e64d76e4-73f8-36e5-9eca-27166bcc890b", FamilyId: "3e31300f-1dcb-1d50-f796-c58c76cb4ab2" }, 
     { ModelTitle: "X6", Id: "b104e806-5652-a21b-0180-a8956246a045", FamilyId: "3e31300f-1dcb-1d50-f796-c58c76cb4ab2" }, 
     { ModelTitle: "X3", Id: "b3447f56-a51b-a451-29de-26b4b3fd98e9", FamilyId: "3e31300f-1dcb-1d50-f796-c58c76cb4ab2" }, 
     { ModelTitle: "530i xDrive", Id: "30595eef-d0a7-a234-dc7f-6670a588c00e", FamilyId: "3d9d6640-a8b5-b4ed-56d2-ef9d1d6f8544" }, 
     { ModelTitle: "740Li", Id: "f19aed7c-f2a8-6777-4ed2-93ef2b717ac3", FamilyId: "c395c655-f302-852a-ccca-1a5e9bf10e0e" }, 
     { ModelTitle: "325Li xDrive", Id: "eaabc23e-d040-34ee-1e59-b1f6b9bc3cff", FamilyId: "9e55c0ae-37d0-0d89-808f-acccfb58562f" }, 
     { ModelTitle: "M3", Id: "e200ffba-e70c-e743-e8b5-8dd39061bd7d", FamilyId: "9e55c0ae-37d0-0d89-808f-acccfb58562f" }, 
     { ModelTitle: "M5", Id: "3d37e4b7-61be-a467-d4b9-aba784dea17b", FamilyId: "3d9d6640-a8b5-b4ed-56d2-ef9d1d6f8544" }, 
     { ModelTitle: "320i", Id: "398ee891-4847-5f29-b7c9-b98249d6b582", FamilyId: "9e55c0ae-37d0-0d89-808f-acccfb58562f" }, 
     { ModelTitle: "550i Sedan", Id: "49e7ca96-d801-ff2c-c112-245b1707e6c1", FamilyId: "3d9d6640-a8b5-b4ed-56d2-ef9d1d6f8544" }, 
     { ModelTitle: "750Li xDrive", Id: "9193cc24-58a8-cb8b-c7d4-f10eddb110b6", FamilyId: "c395c655-f302-852a-ccca-1a5e9bf10e0e" }, 
    ]; 
    optionList = [ 
     { Id: "option01", ModelId: "e1d17dbf-3142-4bde-89bd-830caa09eb93", OptionPrice: "120", OptionType: "0", OptionTitle: "325i Moonroof" }, 
     { Id: "option02", ModelId: "e1d17dbf-3142-4bde-89bd-830caa09eb93", OptionPrice: "150", OptionType: "1", OptionTitle: "325i 19\" Alloy Wheels" }, 
     { Id: "option03", ModelId: "e1d17dbf-3142-4bde-89bd-830caa09eb93", OptionPrice: "180", OptionType: "1", OptionTitle: "325i Remote Keyless Entry" }, 
     { Id: "option04", ModelId: "e1d17dbf-3142-4bde-89bd-830caa09eb93", OptionPrice: "200", OptionType: "0", OptionTitle: "325i Power Locks" }, 
     { Id: "option05", ModelId: "e1d17dbf-3142-4bde-89bd-830caa09eb93", OptionPrice: "520", OptionType: "0", OptionTitle: "325i 6 Speed Automatic" }, 
     { Id: "option06", ModelId: "e1d17dbf-3142-4bde-89bd-830caa09eb93", OptionPrice: "600", OptionType: "1", OptionTitle: "325i Pedal Shifters" }, 
     { Id: "option07", ModelId: "e1d17dbf-3142-4bde-89bd-830caa09eb93", OptionPrice: "540", OptionType: "1", OptionTitle: "325i Heated Front and Back Seats" }, 
     { Id: "option06", ModelId: "f19aed7c-f2a8-6777-4ed2-93ef2b717ac3", OptionPrice: "690", OptionType: "1", OptionTitle: "740Li Touring Package" }, 
     { Id: "option09", ModelId: "f19aed7c-f2a8-6777-4ed2-93ef2b717ac3", OptionPrice: "960", OptionType: "0", OptionTitle: "740Li Illuminating" }, 
     { Id: "option10", ModelId: "9ac7da72-5224-6046-3913-c2700c486682", OptionPrice: "600", OptionType: "0", OptionTitle: "525i 20\" Alloy Wheels" }, 
     { Id: "option11", ModelId: "9ac7da72-5224-6046-3913-c2700c486682", OptionPrice: "320", OptionType: "0", OptionTitle: "525i Tech Package" }, 
     { Id: "option12", ModelId: "9ac7da72-5224-6046-3913-c2700c486682", OptionPrice: "542", OptionType: "1", OptionTitle: "525i Premium Package" }, 
     { Id: "option13", ModelId: "9ac7da72-5224-6046-3913-c2700c486682", OptionPrice: "520", OptionType: "1", OptionTitle: "525i Sports Package" }, 
     { Id: "option14", ModelId: "9ac7da72-5224-6046-3913-c2700c486682", OptionPrice: "540", OptionType: "0", OptionTitle: "525i Heated Back Seats" }, 
     { Id: "option15", ModelId: "9ac7da72-5224-6046-3913-c2700c486682", OptionPrice: "770", OptionType: "1", OptionTitle: "525i Smart Cruise Control" }, 
     { Id: "option16", ModelId: "e64d76e4-73f8-36e5-9eca-27166bcc890b", OptionPrice: "670", OptionType: "1", OptionTitle: "X5 Moonroof" }, 
     { Id: "option17", ModelId: "e64d76e4-73f8-36e5-9eca-27166bcc890b", OptionPrice: "450", OptionType: "0", OptionTitle: "X5 Blind Spot Detection" }, 
     { Id: "option18", ModelId: "b3447f56-a51b-a451-29de-26b4b3fd98e9", OptionPrice: "340", OptionType: "0", OptionTitle: "X3 Heated Seats" }, 
     { Id: "option19", ModelId: "9193cc24-58a8-cb8b-c7d4-f10eddb110b6", OptionPrice: "550", OptionType: "0", OptionTitle: "750Li Smart Stop System" }, 
     { Id: "option20", ModelId: "9193cc24-58a8-cb8b-c7d4-f10eddb110b6", OptionPrice: "870", OptionType: "0", OptionTitle: "750Li Blind Spot Detection" }, 
     { Id: "option21", ModelId: "e200ffba-e70c-e743-e8b5-8dd39061bd7d", OptionPrice: "230", OptionType: "0", OptionTitle: "M3 6 Cylinder Direct Injecton Engine" }, 
     { Id: "option22", ModelId: "e200ffba-e70c-e743-e8b5-8dd39061bd7d", OptionPrice: "450", OptionType: "1", OptionTitle: "M3 8 Speed Automatic Transmission" }, 
     { Id: "option23", ModelId: "e200ffba-e70c-e743-e8b5-8dd39061bd7d", OptionPrice: "650", OptionType: "0", OptionTitle: "M3 6 Speed Manual Transmission" }, 
     { Id: "option24", ModelId: "3d37e4b7-61be-a467-d4b9-aba784dea17b", OptionPrice: "980", OptionType: "1", OptionTitle: "M5 Automatic Moonroof" }, 
    ]; 

** UPDATE 2 **

Здесь я положил все на JSFiddle

https://jsfiddle.net/hhkrjus3/

+0

whoooping количество кода. Не могли бы вы предоставить минимальный пример? И точно сказать, что происходит не так? –

+0

вещь. Когда я нажимаю флажок один раз, значение наблюдаемого массива изменяется, но не отражается на DOM. Но когда я нажимаю на какой-то другой элемент, изменения отражают предыдущие изменения. Вы можете увидеть скрипку, чтобы наблюдать за поведением, поскольку, по моему мнению, мое заявление вызывает путаницу. Извиняюсь. Извините за длинный код :) –

ответ

0

я решил. Событие клика предотвращало выбор. Я не знаю почему, но когда я удалил событие click, он сработал. Обходной путь, который я выбрал, это: Я создал вычисленный флаг в Factory Method. Было бы очень полезно, если кто-то ответит, почему привязка события кликов препятствует отображению формы результатов в DOM.

Спасибо всем :)

0

при работе с флажками, вы должны использовать «проверили» связывания. http://knockoutjs.com/documentation/checked-binding.html

Это, вероятно, решить вашу проблему :)

EDIT: Я был Abit поститься там, я вижу, что вы используете alrdy проверяемого связывания. Но вы также используете привязку значений. Вы должны использовать только один из них, зарегистрированный в этом случае

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