如何使用KnockoutJS
创建函数,我可以调用它来对视图模型进行一些操作?
型号:
public class ViewModel
{
public int User { get; set; }
public string Address { get; set; }
public string ZipCode { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
使用Javascript:
<script type="text/javascript">
var Product = function (Id, Name) {
self = this;
self.Id = Id;
self.Name = Name;
}
function Add() {
viewModel.products.push(new Product(2, "bread"));
}
function Remove(product) {
viewModel.products.remove(product);
}
var viewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));
viewModel.products = ko.observableArray();
ko.applyBindings(viewModel);
Add();
console.log(viewModel.products().length);
var t = new Product(2, "bread");
Remove(t);
console.log(viewModel.products().length);
</script>
在此处添加此类作品,但function Remove(product)
不会从array
中删除该产品。我没有收到错误,console
只打印出1(在viewModel.products().length
次调用中)。
那么如何为KnockoutJS创建适当的函数才能在页面的任何位置调用它们?
答案 0 :(得分:3)
我看不到你的代码有什么明显的东西,它不像你的模型中返回的对象,你的删除实际上是在工作,但剩下的对象是从模型返回的对象?
我更喜欢在从模型中读回对象时映射对象,以避免像这样创建匿名对象:
var mapping = {
'Products': {
create: function(options) {
return new Product(options.data.Id, options.data.Name);
}
}
}
这可确保您的产品是实际的产品对象。
您还可以检查从模型返回的json是这样的:
{ "User": "a", "Address": "b", "ZipCode": "zip", "Products":[{"Id":1,"Name":"jam"}]};
以下是在jsFiddle中工作的完整代码(检查控制台的输出):
这显示,一个从模型返回,一个添加然后删除,一个产品在集合中。
<强>更新强>
您可以通过将模型更改为此来初始化集合服务器端:
public class ViewModel
{
public ViewModel()
{
Products = new List<Product>();
}
public int User { get; set; }
public string Address { get; set; }
public string ZipCode { get; set; }
public List<Product> Products { get; set; }
}
这意味着如果您采用上述方法,则无需执行viewModel.products = ko.observableArray();
。
<强>更新强>
然后你可以重构它以使它给它更好的结构(更模块化):
var Product = function (Id, Name) {
self = this;
self.Id = Id;
self.Name = Name;
}
var mapping = {
'Products': {
create: function(options) {
return new Product(options.data.Id, options.data.Name);
}
}
}
function ProductsViewModel(data) {
var self = this;
ko.mapping.fromJS(data, mapping, self);
self.Add = function Add(product) {
self.Products.push(product);
}
self.Remove = function Remove(product) {
self.Products.remove(product);
}
}
var data = { "User": "a", "Address": "b", "ZipCode": "zip", "Products":[{"Id":1,"Name":"jam"}]};
var viewModel = new ProductsViewModel(data);
ko.applyBindings(viewModel);
// add
var product = new Product(2, "bread");
viewModel.Add(product);
console.log(viewModel.Products());
// remove
viewModel.Remove(product);
console.log(viewModel.Products());
更新了小提琴(再次查看输出控制台):
答案 1 :(得分:2)
var t = new Product(2, "bread");
这会创建一个全新的对象。
Remove(t);
由于t
是全新的,viewmodel.products
中不存在(即使具有相同成员的完全不同的对象),因此remove
之后不会删除任何内容observableArray
的方法如果传递了对象,则使用对象标识。
您可以将Remove
重写为
function Remove(product) {
viewModel.products.remove(function(item) {
return item.Id==product.Id;
});
}
因为将函数传递给remove
方法会导致它删除函数为true的所有项。
您的Product
构造函数中也存在问题:
var Product = function (Id, Name) {
self = this;
self
在这里是全球性的,出于某些棘手的原因,它实际上是window
的别名。使用var
进行前缀。