私はknockout.jsを使用して4つのカスケードドロップダウンを取得しようとしています:
- 検索基準
- 下位基準
- 価値
- 州
次のリンクのコードを使用して、最初のカスケードを実行できました(データバインディングの問題のため、他のカスケードは実行できませんでした)。
http://blogs.msdn.com/b/thebeebs/archive/2011/12/01/price-calculator.aspx
これらのドロップダウンのデータは、ViewBag.CriteriaData変数を使用してMVCビューからSearchCriterionのIEnumrableとしてかみそりのビューページに返されます。私のクラスのコードは次のとおりです。
public class SearchCriterion
{
public string Text { get; set; }
public string Value { get; set; }
public List<SubCriterion> SubCriteria { get; set; }
}
public class SubCriterion
{
public string SearchCriterionValue { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public List<ColumnValue> ColumnValues { get; set; }
}
public class ColumnValue
{
public string SearchCriterionValue { get; set; }
public string SubCriterionValue { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public IEnumerable<StateValue> StateValues { get; set; }
}
public class StateValue
{
public string SearchCriterionValue { get; set; }
public string SubCriterionValue { get; set; }
public string ColumnValue { get; set; }
public IEnumerable<int> InputStateIds { get; set; }
public IEnumerable<int> OutputStateIds { get; set; }
public int SelectedInputStateId { get; set; }
public int SelectedOutputStateId { get; set; }
public string Text { get; set; }
public string Value { get; set; }
}
私が直面している問題は、.cshtmlコードの次の部分にあります。
このテンプレートで他の2つのドロップダウンに何を指定しますか。たとえば、3番目のドロップダウンはColumnValue.Valueにバインドする必要があります(ColumnValueはSubCriterionの一部です)
<script id='criteriaRowTemplate' type='text/html'> <tr> <td><select data-bind='options: criteriaData, optionsText: "Text", optionsCaption: "Search Criterion", value: SearchCriterion' /></td> <td><select data-bind='visible: SearchCriterion, options: SearchCriterion() ? SearchCriterion().SubCriteria : null, optionsText: "Text", optionsCaption: "Sub Criterion", value: SubCriterion' /></td> <td><select data-bind='visible: SubCriterion, options: SubCriterion() ? SubCriterion().ColumnValues : null, optionsText: "Text", optionsCaption: "Column Value", value: ColumnValue'/></td> <td><select data-bind='visible: ColumnValue, options: ColumnValue() ? ColumnValue().StateValues : null, optionsText: "Text", optionsCaption: "State", value: StateValue'/></td> <td><button data-bind='click: function() { viewModel.removeLine($data) }'>Remove</button></td> </tr> </script>
これは正しいです?
var CriteriaLine = function() { this.SearchCriterion = ko.observable(); this.SubCriterion = ko.observable(); this.ColumnValue = ko.observable(); this.StateValue = ko.observable(); // Whenever the Search Criteria changes, reset the Sub Criteria selection this.SearchCriterion.subscribe(function() { this.SubCriterion(undefined); }.bind(this)); this.SubCriterion.subscribe(function() { this.ColumnValue(undefined); }.bind(this)); this.ColumnValue.subscribe(function() { this.StateValue(undefined); }.bind(this));
};
完全なC#オブジェクトをJavascriptオブジェクトにマッピングするにはどうすればよいですか?最初の2つのドロップダウンがある場合に機能します。
// Create a Javascript object object with the same property names as the C# object var dataToSearch = $.map(this.lines(), function (line) { return line.StateValue() ? line.StateValue() : undefined; }); var SearchObject = new function () { this.StateValues = dataToSearch; }; // Convert the object to JSON var searchCriteria = JSON.stringify(SearchObject);
バインディングのためにここで何か変更する必要がありますか?
// Apply the data from the server to the variable var criteriaData = @Html.Raw(@Json.Encode(ViewBag.CriteriaData)); var viewModel = new Criteria(); ko.applyBindings(viewModel, document.getElementById("criteriaDiv"));
編集:
これで、カスケードドロップダウンにデータを入力できるようになりました(上記の更新されたコード)。これで4つの列があり、各列にドロップダウンの1つがあります。また、Knockoutjsを使用して動的に追加される行数は1...nです。したがって、ユーザーはこれらのドロップダウンから値を選択し、必要に応じてドロップダウンの行を追加できるようになりました。残っているのは、ユーザーがドロップダウン用に選択した値をコントローラーに返すことだけです(上記のポイント3)。どうすればいいのかわかりません。どんな助けでもいただければ幸いです。
編集2:
アイテム#3の作業コードを追加し、ColumnValueクラスとStateValueクラスを変更しました。