2013-07-09 87 views
1

我有一種感覺,這不會是一個簡單的問題(或者可能與某些完全不相關的事情有關),但是我要去嘗試一下。我有一個也使用KnockOutJS的ASP.NET MVC頁面。在頁面上有兩個相關的下拉菜單。第一個列出了優惠類型列表。根據您選擇的提供類型,第二個下拉列表需要使用該提供類型的正確選項重新填充。Knockout計算只能觸發一次

這用於在某個時間點工作,但該頁面正在沉重的建設,現在不工作。 當我選擇新的出價類型時,其他下拉列表不會重新填充。

這是DropDown的HTML。你會注意到那裏有一個隱藏的輸入。 當我選擇一個新的OfferType時,它將正確填充OfferTypeId。

<div class="control-group" style="clear: both;"> 
    @Html.LabelFor(m => m.OfferType, new { @class = "control-label" }) 
    <div class="controls"> 
     <select class="input-block-level" id="OfferType" name="OfferType" data-bind="options: offerTypes, value: selectedOfferType, optionsText: 'DisplayName'"></select> 
    </div>@Html.HiddenFor(m => m.OfferTypeId, new { data_bind = "value: selectedOfferType().OfferTypeId" }) 
</div> 

<div class="control-group" style="clear: both;"> 
    @Html.LabelFor(m => m.OfferTypeDetails, new { @class = "control-label" }) 
    <div class="controls"> 
     <select class="input-block-level" id="OfferTypeDetails" name="OfferTypeDetails" data-bind="options: offerDetails, value: selectedOffer, optionsText: 'DisplayName'"></select> 
    </div>@Html.HiddenFor(m => m.OfferTypeDetailsTypeId, new { data_bind = "value: selectedOffer().OfferTypeId" }) 
</div> 

這裏是JavaScript(數據修剪爲簡潔起見):

 $(document).ready(function() {    
      var offerType = function (offerTypeId, displayName, offerTypeDetailsTypes) { 
       var self = this; 
       self.OfferTypeId = offerTypeId; 
       self.DisplayName = displayName; 
       self.OfferTypeDetailsTypes = offerTypeDetailsTypes; 
      }; 

      var offerTypeDetailsType = function (offerTypeDetailsTypeId, displayName, offerTypeId) { 
       var self = this; 
       self.OfferTypeDetailsTypeId = offerTypeDetailsTypeId; 
       self.DisplayName = displayName; 
       self.OfferTypeId = offerTypeId; 
      }; 

      function viewModel() { 
       var self = this; 

       self.selectedOfferType = ko.observable(); 
       self.selectedOffer = ko.observable(); 

       self.offerTypes = ko.observableArray([ 
        new offerType('1', 'Purchase Discount'), 
        new offerType('2', 'Savings'), 
        ... 
       ]); 

       self.offerTypeDetailsTypes = ko.observableArray([ 
        new offerTypeDetailsType('1', 'Spend $10 Get $1 Off', '1'), 
        new offerTypeDetailsType('2', 'Spend $100 Get 10% Off', '1'), 
        new offerTypeDetailsType('3', '$ Half Off', '2'), 
        ... 
       ]);   

       self.offerDetails = ko.computed({ 
        read: function() { 
         var activeCategories = ko.observableArray(); 
         ko.utils.arrayForEach(self.offerTypeDetailsTypes(), function (item) { 
          if (item.OfferTypeId == self.selectedOfferType().OfferTypeId) 
           activeCategories.push(item); 
         }); 
         return activeCategories(); 
        } , deferEvaluation: true 
       });   
      } 
ko.applyBindings(new viewModel()); 
     } 
+1

快速評論託德:在offerDetails你的activeCategories不需要是一個observableArray。一個簡單的JavaScript數組就足夠了。你也可以使用ko.utils.arrayFilter而不是arrayForEach進行過濾。 http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html –

+0

感謝瑞恩,這很有幫助,而且肯定少了很多代碼。 :) –

回答

1

託德,我能得到你的示例代碼沒有任何問題的工作。我只是coppied jsFiddle並刪除MVC Razor和jQuery的東西。

http://jsfiddle.net/zrDtU/

的HTML

<select class="input-block-level" id="OfferType" name="OfferType" data-bind="options: offerTypes, value: selectedOfferType, optionsText: 'DisplayName'"></select> 

<select class="input-block-level" id="OfferTypeDetails" name="OfferTypeDetails" data-bind="options: offerDetails, value: selectedOffer, optionsText: 'DisplayName'"></select> 

JavaScript的

//I can't post a link to jsFiddle without code 
var offerType = function (offerTypeId, displayName, offerTypeDetailsTypes) { 
    var self = this; 
    self.OfferTypeId = offerTypeId; 
    self.DisplayName = displayName; 
    self.OfferTypeDetailsTypes = offerTypeDetailsTypes; 
}; 

var offerTypeDetailsType = function (offerTypeDetailsTypeId, displayName, offerTypeId) { 
    var self = this; 
    self.OfferTypeDetailsTypeId = offerTypeDetailsTypeId; 
    self.DisplayName = displayName; 
    self.OfferTypeId = offerTypeId; 
}; 

function viewModel() { 
    var self = this; 

    self.selectedOfferType = ko.observable(); 
    self.selectedOffer = ko.observable(); 

    self.offerTypes = ko.observableArray([ 
     new offerType('1', 'Purchase Discount'), 
     new offerType('2', 'Savings') 
    ]); 

    self.offerTypeDetailsTypes = ko.observableArray([ 
     new offerTypeDetailsType('1', 'Spend $10 Get $1 Off', '1'), 
     new offerTypeDetailsType('2', 'Spend $100 Get 10% Off', '1'), 
     new offerTypeDetailsType('3', '$ Half Off', '2') 
    ]); 

    self.offerDetails = ko.computed({ 
     read: function() { 
      var activeCategories = ko.observableArray(); 
      ko.utils.arrayForEach(self.offerTypeDetailsTypes(), function (item) { 
       if (item.OfferTypeId == self.selectedOfferType().OfferTypeId) activeCategories.push(item); 
      }); 
      return activeCategories(); 
     }, 
     deferEvaluation: true 
    }); 
} 

ko.applyBindings(new viewModel()); 

它看起來像你的問題是在其他地方。

+0

是的,但是,謝謝你的努力。有一些錯誤的JavaScript,我最終發現它幾乎是偶然的。我仍然不確定爲什麼它在這一個地方打破了這一件事,但是再一次,我現在只是開心而已。 –