如何将数据从输入框更新到可观察列表
how to update data from input box to observable list
我正在设计购物车。
产品列表 (prodList) 显示给客户,当用户单击 "Add" 按钮时,相应的产品显示在购物车列表 (orderList) 中。
orderList上添加的产品数量栏是一个文本类型的输入框。
我有一个递增按钮 (+) 和递减按钮 (-),用于更新数量。
现在我想要的是当用户直接在输入框中输入一个数字时,同样应该得到反映。
我知道我需要尝试使用 observable 元素,但我无法让它工作,也欢迎任何建议和提示。
代码如下
HTML 对于 prodList
<div class="lifticons" data-bind="foreach: prodList">
<div class="iIconGrid2" align= "center">
<a href="#" data-bind="click: $root.addToCart">
<img class="iImageTags" alt="Juices" data-bind="attr: {src: imgPath}">
</a>
<a href="#"><div class="linkProdName" data-bind="click: $root.addToCart, text: ProductName"></div></a>
<div class="ProdPrice"><label>Rs </label><label data-bind="text: ProductPrice" id="lblPrice"></label></div>
<div class="productAdd2"><button class="button" data-bind="click: $root.addToCartViaProdList">Add</button></div>
</div>
</div>
HTML 订单列表
<div data-bind="foreach: orderList">
<div class="OrderData"data-bind="visible: ProductQty">
<div class="horDiv0" data-bind="text: ProductName"></div>
<div class="horDiv25"><span><label>Rs </label><label data-bind="text: ProductPrice"></label></span></div>
<div class="horDivQty">
<a href="#"><label class="minusCircle" data-bind="click: $root.removeFromList">-</label></a>
<input class="editQty"type="text" data-bind="value: ProductQty"/>
<a href="#"><label class="minusCircle" data-bind="click: $root.addToCartViaOrderList">+</label></a>
</div>
</div>
</div>
淘汰代码
function ProdList(ProductID, ProductName, ProductPrice, ProductCartDesc, ProductCategoryID, ProductQty)
{
this.ProductID = ko.observable(ProductID);
this.ProductName = ko.observable(ProductName);
this.ProductPrice = ko.observable(ProductPrice);
this.ProductCartDesc = ko.observable(ProductCartDesc);
this.ProductCategoryID = ko.observable(ProductCategoryID);
this.ProductQty = ko.observable(ProductQty);
}
function ProdListViewModel(prods)
{
var self = this;
self.prodList = ko.mapping.fromJS(data);
self.orderList = ko.computed(function()
{
var orderedItems = [];
/*Save data if browser is closed, still the data of cart will be retrievable*/
if (self.remOrAdd() == "FINISH")
{
localStorage.removeItem("orderListDemo");
return orderedItems;
}
if (localStorage.getItem("orderListDemo") != null)
{
var orderListSaved = [];
var dataSaved = ko.utils.parseJson(localStorage.getItem("orderListDemo"));
orderListSaved = ko.utils.arrayMap(dataSaved, function(item)
{
return new ProdList(item.ProductID, item.ProductName, item.ProductPrice, item.ProductCartDesc, item.ProductCategoryID, item.ProductQty);
});
for(var ctrOrderListSaved = 0 ; ctrOrderListSaved < orderListSaved.length ; ctrOrderListSaved++)
{
if (orderListSaved[ctrOrderListSaved].ProductQty() > 0)
{
orderedItems.push(orderListSaved[ctrOrderListSaved]);
}
}
}
/*Checks whether to increment or decrement the QTY*/
var ctrOrderedItems = 0;
var trackIndex = 0;
var index = -1;
var loopTracker = 0;
if(self.remOrAdd().length > 3)
index = parseInt(self.remOrAdd().substring(3));
if (self.remOrAdd().indexOf("ADD") > -1 && index > -1)
{
$(self.prodList()).each(function(i,e){
if (index > -1 && index == e.ProductID())
{
for(ctrOrderedItems = 0; ctrOrderedItems < orderedItems.length; ctrOrderedItems++)
{
if (e.ProductID() == orderedItems[ctrOrderedItems].ProductID())
{
orderedItems[ctrOrderedItems].ProductQty(orderedItems[ctrOrderedItems].ProductQty() + 1);
break;
}
}
if (ctrOrderedItems >= orderedItems.length)
{
orderedItems.push(e);
orderedItems[orderedItems.length-1].ProductQty(1);
}
}
loopTracker++;
});
}
if (self.remOrAdd().indexOf("REM") > -1 && index > -1)
{
if (orderedItems.length > 0)
if (orderedItems[index].ProductQty() > 1)
orderedItems[index].ProductQty(orderedItems[index].ProductQty() - 1);
else
orderedItems.splice(index,1);
}
localStorage.removeItem("orderListDemo");
self.viewOrderTab(0);
if (orderedItems.length > 0)
{
localStorage.setItem("orderListDemo", ko.toJSON(orderedItems));
self.viewOrderTab(1);
}
return orderedItems;
},this);
self.addToCartViaProdList = function (item, event)
{
/*get current item index*/
/*in dom element $index() is enough but in viewModel a context is to be obtained*/
var context = ko.contextFor(event.target);
var index = context.$index();
var incQty = self.prodList()[index].ProductQty();
var prodID = self.prodList()[index].ProductID();
incQty++;
self.remOrAdd("");
self.remOrAdd("ADD"+prodID);
};
self.addToCartViaOrderList = function (item, event)
{
var context = ko.contextFor(event.target);
var index = context.$index();
//Assumption this button can only be clicked only when the saved data storage is available.
var orderListSaved = [];
var dataSaved = ko.utils.parseJson(localStorage.getItem("orderListDemo"));
orderListSaved = ko.utils.arrayMap(dataSaved, function(item)
{
return new ProdList(item.ProductID, item.ProductName, item.ProductPrice, item.ProductCartDesc, item.ProductCategoryID, item.ProductQty);
});
var prodID = orderListSaved[index].ProductID();
self.remOrAdd("");
self.remOrAdd("ADD"+prodID);
};
self.removeFromList = function(item, event)
{
var context = ko.contextFor(event.target);
var index = context.$index();
self.remOrAdd("");
self.remOrAdd("REM"+index);
};
}
var prodListViewModel = new ProdListViewModel();
ko.applyBindings(prodListViewModel);
它应该可以工作,检查下面的代码片段,无论您在文本框中输入什么值,它只会从那里递增。您的代码中的解析可能存在问题。
下次尽量给出简单易懂的代码运行。
另外你的代码很复杂,尽量把它分成不同的模块,不要在一个文件中添加这么多代码。
function AppViewModel() {
this.ProductQty = ko.observable(0);
this.removeFromList = function() {
var currentVal = parseInt(this.ProductQty());
if (currentVal >= 1) {
this.ProductQty(currentVal - 1);
}
};
this.addToCartViaOrderList = function() {
var currentVal = parseInt(this.ProductQty());
if (isNaN(currentVal)) {
currentVal = 0;
}
this.ProductQty(currentVal + 1);
};
}
// Activates knockout.js
ko.applyBindings(new AppViewModel());
.qty {
font-size: 38px;
}
a {
text-decoration: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<div class="qty">
<a href="#">
<label data-bind="click: $root.removeFromList">-</label>
</a>
<input type="text" data-bind="value: ProductQty" />
<a href="#">
<label data-bind="click: $root.addToCartViaOrderList">+</label>
</a>
</div>
我正在设计购物车。 产品列表 (prodList) 显示给客户,当用户单击 "Add" 按钮时,相应的产品显示在购物车列表 (orderList) 中。
orderList上添加的产品数量栏是一个文本类型的输入框。 我有一个递增按钮 (+) 和递减按钮 (-),用于更新数量。
现在我想要的是当用户直接在输入框中输入一个数字时,同样应该得到反映。
我知道我需要尝试使用 observable 元素,但我无法让它工作,也欢迎任何建议和提示。
代码如下
HTML 对于 prodList
<div class="lifticons" data-bind="foreach: prodList">
<div class="iIconGrid2" align= "center">
<a href="#" data-bind="click: $root.addToCart">
<img class="iImageTags" alt="Juices" data-bind="attr: {src: imgPath}">
</a>
<a href="#"><div class="linkProdName" data-bind="click: $root.addToCart, text: ProductName"></div></a>
<div class="ProdPrice"><label>Rs </label><label data-bind="text: ProductPrice" id="lblPrice"></label></div>
<div class="productAdd2"><button class="button" data-bind="click: $root.addToCartViaProdList">Add</button></div>
</div>
</div>
HTML 订单列表
<div data-bind="foreach: orderList">
<div class="OrderData"data-bind="visible: ProductQty">
<div class="horDiv0" data-bind="text: ProductName"></div>
<div class="horDiv25"><span><label>Rs </label><label data-bind="text: ProductPrice"></label></span></div>
<div class="horDivQty">
<a href="#"><label class="minusCircle" data-bind="click: $root.removeFromList">-</label></a>
<input class="editQty"type="text" data-bind="value: ProductQty"/>
<a href="#"><label class="minusCircle" data-bind="click: $root.addToCartViaOrderList">+</label></a>
</div>
</div>
</div>
淘汰代码
function ProdList(ProductID, ProductName, ProductPrice, ProductCartDesc, ProductCategoryID, ProductQty)
{
this.ProductID = ko.observable(ProductID);
this.ProductName = ko.observable(ProductName);
this.ProductPrice = ko.observable(ProductPrice);
this.ProductCartDesc = ko.observable(ProductCartDesc);
this.ProductCategoryID = ko.observable(ProductCategoryID);
this.ProductQty = ko.observable(ProductQty);
}
function ProdListViewModel(prods)
{
var self = this;
self.prodList = ko.mapping.fromJS(data);
self.orderList = ko.computed(function()
{
var orderedItems = [];
/*Save data if browser is closed, still the data of cart will be retrievable*/
if (self.remOrAdd() == "FINISH")
{
localStorage.removeItem("orderListDemo");
return orderedItems;
}
if (localStorage.getItem("orderListDemo") != null)
{
var orderListSaved = [];
var dataSaved = ko.utils.parseJson(localStorage.getItem("orderListDemo"));
orderListSaved = ko.utils.arrayMap(dataSaved, function(item)
{
return new ProdList(item.ProductID, item.ProductName, item.ProductPrice, item.ProductCartDesc, item.ProductCategoryID, item.ProductQty);
});
for(var ctrOrderListSaved = 0 ; ctrOrderListSaved < orderListSaved.length ; ctrOrderListSaved++)
{
if (orderListSaved[ctrOrderListSaved].ProductQty() > 0)
{
orderedItems.push(orderListSaved[ctrOrderListSaved]);
}
}
}
/*Checks whether to increment or decrement the QTY*/
var ctrOrderedItems = 0;
var trackIndex = 0;
var index = -1;
var loopTracker = 0;
if(self.remOrAdd().length > 3)
index = parseInt(self.remOrAdd().substring(3));
if (self.remOrAdd().indexOf("ADD") > -1 && index > -1)
{
$(self.prodList()).each(function(i,e){
if (index > -1 && index == e.ProductID())
{
for(ctrOrderedItems = 0; ctrOrderedItems < orderedItems.length; ctrOrderedItems++)
{
if (e.ProductID() == orderedItems[ctrOrderedItems].ProductID())
{
orderedItems[ctrOrderedItems].ProductQty(orderedItems[ctrOrderedItems].ProductQty() + 1);
break;
}
}
if (ctrOrderedItems >= orderedItems.length)
{
orderedItems.push(e);
orderedItems[orderedItems.length-1].ProductQty(1);
}
}
loopTracker++;
});
}
if (self.remOrAdd().indexOf("REM") > -1 && index > -1)
{
if (orderedItems.length > 0)
if (orderedItems[index].ProductQty() > 1)
orderedItems[index].ProductQty(orderedItems[index].ProductQty() - 1);
else
orderedItems.splice(index,1);
}
localStorage.removeItem("orderListDemo");
self.viewOrderTab(0);
if (orderedItems.length > 0)
{
localStorage.setItem("orderListDemo", ko.toJSON(orderedItems));
self.viewOrderTab(1);
}
return orderedItems;
},this);
self.addToCartViaProdList = function (item, event)
{
/*get current item index*/
/*in dom element $index() is enough but in viewModel a context is to be obtained*/
var context = ko.contextFor(event.target);
var index = context.$index();
var incQty = self.prodList()[index].ProductQty();
var prodID = self.prodList()[index].ProductID();
incQty++;
self.remOrAdd("");
self.remOrAdd("ADD"+prodID);
};
self.addToCartViaOrderList = function (item, event)
{
var context = ko.contextFor(event.target);
var index = context.$index();
//Assumption this button can only be clicked only when the saved data storage is available.
var orderListSaved = [];
var dataSaved = ko.utils.parseJson(localStorage.getItem("orderListDemo"));
orderListSaved = ko.utils.arrayMap(dataSaved, function(item)
{
return new ProdList(item.ProductID, item.ProductName, item.ProductPrice, item.ProductCartDesc, item.ProductCategoryID, item.ProductQty);
});
var prodID = orderListSaved[index].ProductID();
self.remOrAdd("");
self.remOrAdd("ADD"+prodID);
};
self.removeFromList = function(item, event)
{
var context = ko.contextFor(event.target);
var index = context.$index();
self.remOrAdd("");
self.remOrAdd("REM"+index);
};
}
var prodListViewModel = new ProdListViewModel();
ko.applyBindings(prodListViewModel);
它应该可以工作,检查下面的代码片段,无论您在文本框中输入什么值,它只会从那里递增。您的代码中的解析可能存在问题。
下次尽量给出简单易懂的代码运行。 另外你的代码很复杂,尽量把它分成不同的模块,不要在一个文件中添加这么多代码。
function AppViewModel() {
this.ProductQty = ko.observable(0);
this.removeFromList = function() {
var currentVal = parseInt(this.ProductQty());
if (currentVal >= 1) {
this.ProductQty(currentVal - 1);
}
};
this.addToCartViaOrderList = function() {
var currentVal = parseInt(this.ProductQty());
if (isNaN(currentVal)) {
currentVal = 0;
}
this.ProductQty(currentVal + 1);
};
}
// Activates knockout.js
ko.applyBindings(new AppViewModel());
.qty {
font-size: 38px;
}
a {
text-decoration: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<div class="qty">
<a href="#">
<label data-bind="click: $root.removeFromList">-</label>
</a>
<input type="text" data-bind="value: ProductQty" />
<a href="#">
<label data-bind="click: $root.addToCartViaOrderList">+</label>
</a>
</div>