我正在尝试使用knockout.js将对象轻松绑定到视图;然而, 我已经到了一个我不明白发生了什么的地步...... 出于某种原因,我的观点没有受到约束。在我的页面上,我有一个包含产品类别列表的下拉列表。更改类别后,我想使用属于所选类别的产品信息填充html表。
以下是我正在使用的代码。
HTML:
<asp:DropDownList ID="ddlProductCategory" runat="server" ClientIDMode="Static">
</asp:DropDownList>
<div id="divProducts">
<table width='100%' border="1">
<thead>
<tr>
<th width='25%'>
Product ID
</th>
<th width='25%'>
Product Name
</th>
<th width='15%'>
Supplier ID
</th>
<th width='10%'>
Category ID
</th>
<th>
QuantityPerUnit
</th>
<th>
UnitPrice
</th>
<th>
UnitsInStock
</th>
<th>
UnitsOnOrder
</th>
</tr>
</thead>
<tbody data-bind="foreach: Products">
<tr>
<td>
<span data-bind="text: ProductID"> </span>
</td>
<td>
<span data-bind="text: ProductName"> </span>
</td>
<td>
<span data-bind="text: SupplierID"> </span>
</td>
<td>
<span data-bind="text: CategoryID"> </span>
</td>
<td>
<span data-bind="text: QuantityPerUnit"> </span>
</td>
<td>
<span data-bind="text: UnitPrice"> </span>
</td>
<td>
<span data-bind="text: UnitsInStock"> </span>
</td>
<td>
<span data-bind="text: UnitsOnOrder"> </span>
</td>
<td>
<a href='#' data-bind='click: $parent.removeLine'>Remove</a>
</td>
</tr>
</tbody>
</table>
</div>
在服务器.NET JavaScriptSerializer对象上获取json表示 产品对象列表:
[WebMethod(EnableSession = true)]
[System.Web.Script.Services.ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)]
public object ProcessRequest(string oData)
{
// Some code to get listOfProducts
var json = new JavaScriptSerializer().Serialize(listOfProducts);
return json;
}
这是我的ViewModel对象:
function ProductsListViewModel (bindingData) {
var self = this;
this.Products = {};
//////////////////////////////////////////////
// Load
/////////////////////////////////////////////
this.BindViewModel = function (jsonProducts) {
var _bindingData = jsonProducts;
if (_bindingData && ObjectTypeChecker.IsJsonObject(_bindingData)) {
_bindingData = $.parseJSON(_bindingData);
}
if (_bindingData && _bindingData.d) {
_bindingData = eval(_bindingData.d);
}
self.Products = _bindingData;
ko.mapping.fromJS(self.Products, self);
};
this.InitialLoad = function()
{
var _bindingData = bindingData;
if (_bindingData && ObjectTypeChecker.IsJsonObject(_bindingData)) {
_bindingData = $.parseJSON(_bindingData);
}
if (_bindingData && _bindingData.d) {
_bindingData = eval(_bindingData.d);
}
self.Products = _bindingData;
ko.mapping.fromJS(self.Products, {});
}
this.InitialLoad();
////////////////// STATIC METHODS ////////////////////////////
ProductsListViewModel.GetCurrentModel = function () {
return self;
}
};
在客户端,在第一次加载时,我正在使用空值初始化我的viewmodel,从服务器获取对象的“元数据”,这完全正常:
$(document).ready(function () {
// Call server for metadata
var agent = new WtrStpJsAgent("WtrStpWireHandler", "NorthwindActionHandler", "GetMetadata", ["Products"]);
var jsonProducts = agent.GetMetadata();
// Now Load initial state for viewmodel
LoadModels();
});
// Load metadata for all viewmodels
function LoadModels() {
var agent = new WtrStpJsAgent("WtrStpWireHandler", "NorthwindActionHandler", "GetMetadata", ["Products"]);
var jsonProducts = agent.GetMetadata();
// Load ProductListViewModel //////////////////////////////////
myProductsViewModel = new ProductsListViewModel(jsonProducts);
ko.applyBindings(myProductsViewModel);
///////////////////////////////////////////////////////////////
}
之后每当下拉列表中的值发生变化时,我都会调用JQuery.ajax方法来获取产品信息,我试图将返回的数据绑定到View:
// Event Handler for Categories Drpdown
function onCategoryChange(event) {
// get data
var agent = new WtrStpJsAgent("WtrStpWireHandler", "NorthwindActionHandler", event.type, event.eventArgs);
var jsonProducts = agent.GetProductsByCategory(event.eventArgs);
// jsonProducts is a list of products in json format:
// {"d":" [{\"ProductID\":1,\"ProductName\":\"Chai\",\"SupplierID\":1,\"CategoryID \":1,\"QuantityPerU nit\":\"10 boxes x 20 bags\",\"UnitPrice\":18.0000,\"UnitsInStock\":39,\"UnitsOnOrder\":0},
// {\"ProductID\":2,\"ProductName\":\"Chang\",\"SupplierID\":1,\"CategoryID\":1,\"QuantityPerUnit\":\"24 - 12 oz bottles\",\"UnitPrice\":19.0000,\"UnitsInStock\":17,\"UnitsOnOrder\":40}]"}
// Re-bind view
BindView(jsonProducts);
}
function BindView(jsonProducts) {
ProductsListViewModel.GetCurrentModel().BindViewModel(jsonProducts);
}
请帮助!
这是我上一篇文章的更新。我发现以下工作正常:
var myProductsViewModel = null;
$(document).ready(function () {
// Load all models
LoadModels();
});
function onCategoryChange(event) {
var agent = new WtrStpJsAgent("WtrStpWireHandler", "NorthwindActionHandler", event.type, event.eventArgs);
var jsonProducts = agent.GetProductsByCategory(event.eventArgs);
BindView(jsonProducts);
}
function LoadModels() {
var agent = new WtrStpJsAgent("WtrStpWireHandler", "NorthwindActionHandler", "GetMetadata", ["Products"]);
var jsonProducts = agent.GetMetadata();
// Load ProductListViewModel //////////////////////////////////
///////////////////////////////////////////////////////////////
if (jsonProducts && ObjectTypeChecker.IsJsonObject(jsonProducts)) {
bbbData = $.parseJSON(jsonProducts);
}
if (bbbData && bbbData.d) {
list = eval(bbbData.d);
}
this.Products = list;
myProductsViewModel = ko.mapping.fromJS(this.Products, {});
ko.applyBindings(myProductsViewModel);
}
function BindView(jsonProducts) {
if (jsonProducts && ObjectTypeChecker.IsJsonObject(jsonProducts)) {
zzzz = $.parseJSON(jsonProducts);
}
if (zzzz && zzzz.d) {
lllll = eval(zzzz.d);
}
this.Products = lllll;
ko.mapping.fromJS(this.Products, myProductsViewModel);
}
但这不起作用:
$(document).ready(function () {
// Load all models
LoadModels();
});
function onCategoryChange(event) {
var agent = new WtrStpJsAgent("WtrStpWireHandler", "NorthwindActionHandler", event.type, event.eventArgs);
var jsonProducts = agent.GetProductsByCategory(event.eventArgs);
BindView(jsonProducts);
}
function LoadModels() {
var agent = new WtrStpJsAgent("WtrStpWireHandler", "NorthwindActionHandler", "GetMetadata", ["Products"]);
var jsonProducts = agent.GetMetadata();
// Load ProductListViewModel //////////////////////////////////
myProductsViewModel = new ProductsListViewModel(jsonProducts);
ko.applyBindings(myProductsViewModel);
}
function BindView(jsonProducts) {
ProductsListViewModel.GetCurrentModel().BindViewModel(jsonProducts);
}
但是我仍然希望保持代码更精细,所以我喜欢使用后面的解决方案中描述的JS对象...因此,任何想法为什么它不起作用????
仍然需要帮助请: - )
答案 0 :(得分:0)
如果您正在使用KnockoutJS并希望在更改var时更新UI,则需要使其可观察。
function ProductsListViewModel (bindingData) {
var self = this;
this.Products = ko.observableArray();
//////////////////////////////////////////////
// Load
/////////////////////////////////////////////
this.BindViewModel = function (jsonProducts) {
var _bindingData = jsonProducts;
if (_bindingData && ObjectTypeChecker.IsJsonObject(_bindingData)) {
_bindingData = $.parseJSON(_bindingData);
}
if (_bindingData && _bindingData.d) {
_bindingData = eval(_bindingData.d);
}
self.Products(_bindingData);
ko.mapping.fromJS(self.Products, self);
};
另请查看http://knockoutjs.com/documentation/observableArrays.html