我使用本教程http://www.dotnetcurry.com/aspnet/1006/edit-html-table-crud-knockoutjs-aspnet-webapi使用KnockOutJS创建一个可编辑的表,而不添加ASP.NET内容(只有KO部分,服务器端API在PHP中实现)。 该教程有效,但我添加了一个新功能,但并没有。我没有输出文本字段,而是修改了作者的指令,在表格中添加了一个按钮而不是它。我想要实现的是读取文件图像的内容,将其存储在变量中并附加在POST有效负载中,以便存储在数据库表的blob字段中。
有人可以建议另一种方法来实现这一目标或指导我纠正现有的方法吗?我是KnockOutJS的新手,还有Javascript。
var self = this;
//S1:Boolean to check wheather the operation is for Edit and New Record
var IsNewRecord = false;
// filename to be converted into string for uploading
var ImgFile = "";
var handleFileSelect = function(evt) {
var files = evt.target.files;
var file = files[0];
//console.log("In handleFileSelect");
if (files && file) {
var reader = new FileReader();
reader.onload = function(readerEvt) {
ImgFile = readerEvt.target.result;
//console.log("Printing the base64 ...");
//console.log(readerEvt.target.result);
};
reader.readAsBinaryString(file);
}
};
function executeCreateListener() {
if (window.File && window.FileReader && window.FileList && window.Blob) {
//console.log("In if");
document.getElementById('filePicker').addEventListener('change', handleFileSelect, false); // this sh** resolves to null due to KO dynamic nature
} else {
alert('The File APIs are not fully supported in this browser.');
}
}
self.ProductsApallou = ko.observableArray([]);
loadProducts();
//S2:Method to Load all Products by making call to WEB API GET method
function loadProducts() {
alert("Loading Data");
$.ajax({
type: "GET",
url: "http://127.0.0.1/goandwin/store_products.json?retrieve:Store_of_Product=1+Store_Product_id=999+Name=999+Subname=999+Imgname=999+Price=999+Product_Discount=999+Slogan=999+Origin=999+Description=999+Product_Code=999+Category_level_1_id=999+Product_Photo=999",
dataType: "json",
}).done(function(data) {
self.ProductsApallou(data);
}).fail(function(err) {});
alert("Success");
};
//S3:The Product Object
function Product(soproduct, spid, pname, subname, imgname, price, product_disc, slogan, origin, descript, product_code, cbid, pphoto) {
return {
Store_of_Product: ko.observable(soproduct),
Store_Product_id: ko.observable(spid),
Name: ko.observable(pname),
Subname: ko.observable(subname),
Imgname: ko.observable(imgname),
Price: ko.observable(price),
Product_Discount: ko.observable(product_disc),
Slogan: ko.observable(slogan),
Origin: ko.observable(origin),
Description: ko.observable(descript),
Product_Code: ko.observable(product_code),
Category_level_1_id: ko.observable(cbid),
Product_Photo: ko.observable(pphoto)
}
};
//S4:The ViewModel where the Templates are initialized
var ProdViewModel = {
readonlyTemplate: ko.observable("readonlyTemplate"),
editTemplate: ko.observable()
};
//S5:Method to decide the Current Template (readonlyTemplate or editTemplate)
ProdViewModel.currentTemplate = function(tmpl) {
return tmpl === this.editTemplate() ? 'editTemplate' : this.readonlyTemplate();
}.bind(ProdViewModel);
//S6:Method to create a new Blank entry When the Add New Record button is clicked
ProdViewModel.addnewRecordApallou = function() {
self.ProductsApallou.push(new Product(1, "auto", "default", "default", "default", 0, 0, "default", "default", "default", "default", 1, "default"));
IsNewRecord = true;
};
//S7:Method to Save the Record (This is used for Edit and Add New Record)
ProdViewModel.saveProduct = function(d) {
var Prod = {};
//console.log(d);
Prod.Store_of_Product = d.Store_of_Product;
Prod.Store_Product_id = d.Store_Product_id;
Prod.Name = d.Name ? d.Name : null;
Prod.Subname = d.Subname ? d.Subname : null;
Prod.Imgname = d.Imgname ? d.Imgname : null;
Prod.Price = d.Price ? d.Price : 0.0;
Prod.Product_Discount = d.Product_Discount ? d.Product_Discount : 0;
Prod.Slogan = d.Slogan ? d.Slogan : null;
Prod.Origin = d.Origin ? d.Origin : null;
Prod.Description = d.Description ? d.Description : null;
Prod.Product_Code = d.Product_Code ? d.Product_Code : null;
Prod.Category_level_1_id = d.Category_level_1_id ? d.Category_level_1_id : 1;
//console.log("Printing imgfile ...");
//console.log(ImgFile);
// <---- HERE what I am trying to achieve, if possible
if (ImgFile) {
Prod.Product_Photo = ImgFile; //take the string produced after uploaded
} else {
Prod.Product_Photo = d.Product_Photo; //take the string as it was
}
// ---->
//Edit the Record
if (IsNewRecord === false) {
$.ajax({
type: "PUT",
url: "http://127.0.0.1/goandwin/store_products/" + Prod.Store_Product_id,
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: Prod
}).done(function(data) {
alert("Record Updated Successfully " + data.status);
ProdViewModel.reset();
}).fail(function(err) {
alert("Error Occured, Please Reload the Page and Try Again " + err.status);
ProdViewModel.reset();
});
}
//The New Record
if (IsNewRecord === true) {
var tmp = Prod;
delete tmp.Store_Product_id; //remove the PK which is auto
IsNewRecord = false;
$.ajax({
type: "POST",
url: "http://127.0.0.1/goandwin/store_products",
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data: tmp
}).done(function(data) {
alert("Record Added Successfully " + data.status);
ProdViewModel.reset();
loadProducts();
}).fail(function(err) {
alert("Error Occured, Please Reload the Page and Try Again " + err.status);
ProdViewModel.reset();
});
}
}
//S8:Method to Delete the Record
ProdViewModel.deleteProduct = function(d) {
$.ajax({
type: "DELETE",
url: "http://127.0.0.1/goandwin/store_products/" + d.Store_Product_id
}).done(function(data) {
//console.log(d.Store_Product_id);
alert("Record Deleted Successfully " + data.status);
ProdViewModel.reset();
loadProducts();
}).fail(function(err) {
alert("Error Occured, Please Reload the Page and Try Again " + err.status);
ProdViewModel.reset();
});
}
//S9:Method to Reset the template
ProdViewModel.reset = function(t) {
this.editTemplate("readonlyTemplate");
};
ko.applyBindings(ProdViewModel);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="tab-content">
<div id="Apallou" class="tab-pane fade in inactive">
<table class="table table-striped table-bordered table-hover" id="dataTables-exampleApallou">
<thead>
<tr>
<th>Store_of_Product</th>
<th>Store_Product_id</th>
<th>Name</th>
<th>Subname</th>
<th>Imgname</th>
<th>Price</th>
<th>Product_Discount</th>
<th>Slogan</th>
<th>Origin</th>
<th>Description</th>
<th>Product_Code</th>
<th>Category_level_1_id</th>
<th>Product_Photo</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="template: { name: currentTemplate, foreach: ProductsApallou }"></tbody>
</table><br><input type="button" value="Add New Record" data-bind="click: function () { ProdViewModel.addnewRecordApallou(); }" /><br></div>
</div>
</div>
</div>
</div>
</div>
<!-- /#wrapper -->
<script type="text/html" id="readonlyTemplate">
<tr>
<td><span data-bind="text: Store_of_Product"></span></td>
<td><span data-bind="text: Store_Product_id"></span></td>
<td><span data-bind="text: Name"></span></td>
<td><span data-bind="text: Subname"></span></td>
<td><span data-bind="text: Imgname"></span></td>
<td><span data-bind="text: Price"></span></td>
<td><span data-bind="text: Product_Discount"></span></td>
<td><span data-bind="text: Slogan"></span></td>
<td><span data-bind="text: Origin"></span></td>
<td><span data-bind="text: Description"></span></td>
<td><span data-bind="text: Product_Code"></span></td>
<td><span data-bind="text: Category_level_1_id"></span></td>
<td><img width="60px" height="70px" data-bind="attr:{src: Product_Photo}" /></td>
<td>
<input type='button' value='Edit' data-bind='click: function () { ProdViewModel.editTemplate($data);}'>
</td>
<td>
<input type='button' value='delete' data-bind='click: function () { ProdViewModel.deleteProduct($data); }'>
</td>
</tr>
</script>
<script type="text/html" id="editTemplate">
<tr>
<td><input type='text' data-bind='value: $data.Store_of_Product' /></td>
<td><input type='text' data-bind='value: $data.Store_Product_id' disabled='disabled' /></td>
<td><input type='text' data-bind='value: $data.Name' /></td>
<td><input type='text' data-bind='value: $data.Subname' /></td>
<td><input type='text' data-bind='value: $data.Imgname' /></td>
<td><input type='text' data-bind='value: $data.Price' /></td>
<td><input type='text' data-bind='value: $data.Product_Discount' /></td>
<td><input type='text' data-bind='value: $data.Slogan' /></td>
<td><input type='text' data-bind='value: $data.Origin' /></td>
<td><input type='text' data-bind='value: $data.Description' /></td>
<td><input type='text' data-bind='value: $data.Product_Code' /></td>
<td><input type='text' data-bind='value: $data.Category_level_1_id' /></td>
<td>
<div><label for="filePicker">Choose a file:</label><input type="file" id="filePicker"></div>
</td>
<td>
<input type="button" value="Save" data-bind="click: ProdViewModel.saveProduct" />
</td>
<td>
<input type="button" value="Cancel" data-bind="click: function () { ProdViewModel.reset(); }" />
</td>
</tr>
</script>
&#13;
我知道我对我尝试做的事情的解释是模糊不清的,所以请随意提出问题以便明确。如果有人想要查看(dpesios,测试),我的项目就是here。