jQuery Datalink not working with object methods
I have a javascript object with several properties. The object also contains an instance method that returns the result of a calculation on two of the object's properties.
I'm using the new Jquery .link() plugin (http://api.jquery.com/link/), to update the UI and form elements with the object property values and vice versa, whenever either the form or the object is updated.
This is all working except for one of the form elements, which should contain the result of the object's instance method but never gets updated.
I've put a button on the form to manually check the value of Discrepancy, and this works but the jquery link plugin is not populating the input elements automatically, although it is populating the input elements linked to the object properties. All elements have an id and name attributes.
Can anyone tell me where I'm going wrong?
My javascript:
<script>
function Product() {
this.InStock = 0;
this.Ordered = 0;
}
// object's instance method
Product.prototype.Discrepancy = ComputeDiscrepancy;
function ComputeDiscrepancy() {
return this.InStock - this.Ordered;
}
$(document).ready(function () {
var products = new Array();
products[0] = new Product();
products[1] = new Product();
$("form").link(products[0], {
InStock: "product0_InStock"开发者_JS百科,
Ordered: "product0_Ordered",
Discrepancy: "product0_Discrepancy"
});
$("form").link(products[1], {
InStock: "product1_InStock",
Ordered: "product1_Ordered",
Discrepancy: "product1_Discrepancy"
});
// button for me to manually check discrepancy method works
$("#checkData").click(function () {
alert(products[0].InStock);
$("#product0_Discrepancy").val(products[0].Discrepancy());
});
}); </script>
HTML:
<table>
<tr>
<th></th><th>Product 1</th><th>Product 2</th>
</tr>
<tr>
<td> In Stock</td>
<td><input id="product0_InStock" name="product0_InStock"/></td>
<td><input id="product1_InStock" name="product1_InStock"/></td>
</tr>
<tr>
<td>Ordered</td>
<td><input id="product0_Ordered" name="product0_Ordered"/></td>
<td><input id="product1_Ordered" name="product1_Ordered"/></td>
</tr>
<tr>
<td>Discrepancy</td>
<td><input id="product0_Discrepancy" name="product0_Discrepancy"/></td>
<td><input id="product1_Discrepancy" name="product1_Discrepancy"/></td>
</tr>
</table>
The problem is that Discrepancy is a method of a Product object and not a property. You can't link a DOM element to a method, only to a property.
The way I solved the problem is to (a) make Discrepancy a property, and (b) use the convert and convertBack methods in order to ensure that this new property was updated properly.
Here's my script block:
function Product() {
this.InStock = 0;
this.Ordered = 0;
this.Discrepancy = 0;
}
var products = [];
$(document).ready(function () {
products[0] = new Product();
products[1] = new Product();
var calcDiscrepancy = function(value, source, target) {
$(target).data("Discrepancy", target.InStock - target.Ordered);
return value;
};
var changeInStock = function (value, source, target) {
target.InStock = value;
return calcDiscrepancy(value, source, target) ;
};
var changeOrdered = function (value, source, target) {
target.Ordered = value;
return calcDiscrepancy(value, source, target) ;
};
var showDiscrepancy = function(value, source, target) {
$(target).text(value.toString());
};
$("form").link(products[0], {
InStock: {
name: "product0_InStock",
convert: changeInStock
},
Ordered: {
name: "product0_Ordered",
convert: changeOrdered
},
Discrepancy: {
name: "product0_Discrepancy",
convertBack: showDiscrepancy
}
});
$("form").link(products[1], {
InStock: {
name: "product1_InStock",
convert: changeInStock
},
Ordered: {
name: "product1_Ordered",
convert: changeOrdered
},
Discrepancy: {
name: "product1_Discrepancy",
convertBack: showDiscrepancy
}
});
});
Going through it:
add the
Discrepancyproperty to theProductclass, with default 0. Throw away the ComputeDiscrepancy stuff.write a couple of functions that take note of changes in
InStockandOrdered. These will update the relevant properties of the target object and then call a function calledcalcDiscrepancyand return its return value.calcDiscrepancywill update the value to the target object'sDiscrepancyproperty. To ensure that all the events are triggered with this change, I used jQuery's.data()method.write a
showDiscrepancymethod that would update the target's contents with the value passed in (the target is going to be the DOM element). I also changed the "discrepancy" elements to rather than text boxes: it didn't make sense otherwise.The calls to
link()now map the relevant DOM elements to the relevant properties and specify converters for each. For the InStock property the converter is a convert type and callschangeInStock, etc. For the Discrepancy property, the converter is a convertBack type that callsshowDiscrepancy. (In essenceconvertgoes from the DOM element to the object property, andconvertBackgoes from the property to the element.)
加载中,请稍侯......
精彩评论