2014-01-17 66 views
0

我只是試圖填充一對夫婦,我用jQuery渲染選擇標籤。我如何使用淘汰賽js和jquery填充選擇標籤?

從服務器傳入模式:

public class DepthChartsVm 
{ 
    public List<DepthChartModel> ReturnDepthCharts {get;set;} 
} 

public class DepthChartModel 
{ 
    public Team Team {get;set;} 
    public int SportId {get;set;} 
} 

public class Team 
{ 
    // various properties 
    public List<AthleteInfo> AthleteInfo {get;set;} 
    public List<positions> BasketBallPositonList {get;set;} 
} 

public class AthleteInfo 
{ 
    // various properties 
    List<DepthChart> DepthChartPositions {get;set;} 
} 

public class DepthChart 
{ 
    // various properties 
    prop ...etc 
} 

public class Positions 
{ 
    // various properties 
    prop ... etc. 
} 

HTML:

       <div class="col-sm-4"> 
      <label for="teamDropDown" class="text-center">Teams</label> 
      <select id="teamDropDown" data-bind="options: depthVm.ReturnDepthCharts, value: selectedTeam, 
       optionsText: function(item){return item.Team.FullName}, 
       optionsCaption: 'select'"></select> 
      <p data-bind="if: selectedTeam"> 
       <strong>Sport: </strong> <span data-bind="text: selectedTeam().Team.Sport"></span><br /> 
       <strong>Season: </strong> <span data-bind="text: selectedTeam().Team.Season"></span> 
      </p> 
     </div> 
     <!--Athletes--> 
     <div class="col-sm-4"> 
      <div data-bind="if: selectedTeam"> 
       <h3 class="text-center">Athletes</h3> 
       <div data-bind="foreach: selectedTeam().Team.AthleteInfo"> 
        <p> 
         <strong>Name: </strong><span data-bind="text: FirstName() 
          + ' ' + LastName()"></span> 
        </p> 
        <div data-bind="foreach: DepthChartPositions()"> 
         <p> 
          <input class="hidden" name="InputUpdateDepthChart.RosterId" 
            data-bind="value: RosterId"/> 
          Position: <select name="InputUpdateDepthChart.PositionId" 
            data-bind="options: $root.selectedTeam().Team.BasketBallPostionList, 
            optionsText: 'Position', value: PositionId, optionsValue: 'Id'"></select> 
          String: <select name="InputUpdateDepthChart.StringId" 
            data-bind="options: DepthStrings, optionsText: 'String', 
             value: StringId, optionsValue: 'Id'"></select> 
         </p> 
         <p> 
          <button data-bind="click: $root.addPosition">Add Position</button> 
         </p> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 
    // script that serializes the model and passes it to knockout 
    <script> 
     // json encode incoming model 

     var depthModelData = @Html.Raw(JsonConvert.SerializeObject(Model)) 

     // update depth chart vM 
     ko.applyBindings(new UpdateDepthChartVm(depthModelData), 
      document.getElementById('updateDepthChartForm')); 
    </script> 

視圖模型:

    var UpdateDepthChartVm = function (model) { 
var self = this; 
self.depthVm = ko.mapping.fromJS(model); 

// selected team 
self.selectedTeam = ko.observable(); 

// add position 
self.addPosition = function() { 

    self.selectedTeam.Team.AthleteInfo.DepthChartPositions.push(new depthChartPosition()); 
}; 

function depthChartPosition(values) { 
    values = values || {}; 
    var model = { 
     RosterId: ko.observable(values.RosterId), 
     PositionId: ko.observable(values.PositionId), 
     StringId: ko.observable(values.StringId), 
    }; 
    return model; 
} 

};

基本上我想要當用戶希望增加另一個位置複製在飛行的第一段。 jquery確實在使用select標籤呈現新段落方面起作用,但是select字段是空的,因爲看起來它們和我的視圖模型之間沒有綁定。除此之外,我的視圖模型正在工作。我在這裏錯過了什麼?

回答

1

Knockout Mapping只會在所提供對象的第一級中的屬性周圍添加可觀察的包裝。我假設你送入ko.mapping.fromJS方法的對象是DepthChartsVm C#模型的JS表示。因此,只有ReturnDepthCharts財產將是可觀察的。簡單的答案是提供自定義映射,如:

var depthChartsVmMapping = { 
    Team: { 
     create: function(options) { 
      return ko.mapping.fromJS(options.data, teamMapping); 
     } 
    } 
} 
var teamMapping = { 
    AthleteInfo: { 
     create: function(options) { 
      return ko.mapping.fromJS(options.data, athleteInfoMapping); 
     } 
    } 
} 
var athleteInfoMapping = { 
    DeptChartPositions: { 
     create: function(options) { 
      return ko.mapping.fromJS(options.data); 
     } 
    } 
} 

var self = this; 
self.depthVm = ko.mapping.fromJS(model, depthChartsVmMapping); 

是的,我同意這使得映射模塊顯得有點累贅,但考慮到模型中包含了太多的水平的可能性。例如,你是否真的需要加載所有隊伍,所有運動員,以及每個運動員的深度圖表位置?更傳統的類似REST的實現可能是在需要時異步加載必要的資源。顯然,我不知道你的應用程序是如何呈現的,但我直覺地認爲,在這種情況下,你可能有:

  • 一團隊的observableArray;最初僅包含摘要信息
  • 可觀察到存儲當前選定的團隊
  • 的操作來獲得球隊的詳細信息(其中可能包括與深度圖信息的運動員

你可以用自定義你的映射工作上面所列舉的,所以如果你不跟着我不要擔心。但是,如果你因爲某些重構,我認爲反彈背後的原因!

希望幫助!

var vm = { 
    Teams: ko.observableArray(), 
    CurrentTeam: ko.observable(), 
} 
+0

無論出於何種原因,SO不會讓我對我以前的答案進行編輯,所以我必須提交一個新的。抱歉耽擱了。我希望編輯提交錯誤將被整理出來。 –

+0

好吧,現在我感覺特別密集。所以我最初理解了映射的概念,但我對如何將其實際應用到視圖模型感到困惑。我的意思是因爲有幾個屬性需要映射,我必須爲每個映射調用ko.mapping嗎?例如,在上面的代碼中,您有self.depthVm = ko.mapping.fromJs(model,modelMappings); modelMappings在哪裏定義?或者我必須一遍又一遍地調用該語句,並用每個單獨定義的映射替換modelMapping? – user1206480

+0

對不起modelMappings是一個錯誤。它現在糾正了。同樣,ko映射不會遞歸探索您的模型以在每個級別創建可觀察屬性。相反,只有提供模型的直接子項的屬性纔是可觀察的。這很有意義嗎? –

1

後續選擇的元素沒有任何選擇的原因是因爲他們沒有約束。請記住,ko.applyBindings是讓您的HTML生活的話題。由於這些項目是在事後添加的,因此它們不會被ko跟蹤。

其實是有一個更好的方式與淘汰賽的observableArray做到這一點。它更清潔,乾燥,可測試。你太親近了!

var UpdateDepthChartVm = function (model) { 
var self = this; 
self.depthVm = ko.mapping.fromJS(model); 

self.selectedTeam = ko.observable(); 

self.addPosition = function() { 
    self.depthVm.DepthChartPositions.splice(0, 0, new depthChartPosition()); 
    // I used splice because I believe you were wanting the UI element to be added to the 
    // top of the list. Otherwise you could just use `push(new depthChartPosition())`. 
}; 

// this bit isn't required but it's my preference 
function depthChartPosition(values) { 
    values = values || {}; 
    var model = { 
     RosterId: ko.observable(values.RosterId), 
     PositionId: ko.observable(values.PositionId), 
     StringId: ko.observable(values.StringId), 
    } 
    return model; 
} 

// you also might want to use the above constructor in your mapping. again, just my preference 
function mappings() { 
    return { 
     DepthChartPositions: { 
      create: function(options) { 
       return new depthChartPosition(options.data); 
      } 
     } 
    } 
} 

請記住,knockout.js是一個MVVM(模型視圖視圖模型)框架。讓視圖模型數據在不知道UI的情況下驅動UI,同時儘可能簡化UI。

編輯

以在您的視圖模型仔細看,我看到有兩個DepthChartPositions:一self.depthVm成員(這應該是一個observableArray感謝ko.mapping),其他的selectedTeam().Team.AthleteInfo 。後者是UI元素綁定的對象。我確實看到你的addPosition函數正在修改正確的對象,但是我不知道如何創建這個對象。我的猜測是,這不是一個observableArray。您可以像這樣測試它:

ko.isObservable(self.selectedTeam.Team.AthleteInfo.DepthChartPositions) 
+0

因此,我試圖對代碼進行建議的更改,但它仍然無法正常工作。此時我懷疑它可能與對象嵌套在視圖模型中的方式有​​關,所以我更新了上面的html以反映整個視圖模型。希望這可以讓我瞭解我在這裏做錯了什麼。再次,一切都在努力,直到self.addPosition函數。 – user1206480

+0

你可以驗證'self.selectedTeam.Team.AthleteInfo.DepthChartPositions'是一個observableArray嗎? –

+0

你在問錯人,哈哈!但是,嚴重的是,我現在有點頭痛。我假設它是可觀察的,因爲整個模型是通過ko.mapping引入的,但我是全新的淘汰賽,所以我不太確定。 – user1206480