剛剛自學knockoutjs,總是碰到稀奇古怪的問題。javascript
在自學knockout.js的時候常常遇到 Unable to process binding "value:的問題。目前總結了如下幾種狀況:html
1.model與view進行binding的時候,與在本身的viewModel中自定義的變量名稱不一致;java
2.針對全局的html頁面進行了屢次ko.applyBindings(new Cart());app
在這種狀況下,能夠添加好須要綁定的block對應的id:ko.applyBindings(new Cart(),document.getElementById("block_id"));this
3.對頁面使用div或者其餘元素進行了不一樣block的劃分,好比下面的形式:spa
<div id="head">
<div></div>
</div>code
<div id="main">
<div></div>
</div>orm
<div id="foot">
<div></div>
</div>server
那麼在自定義的viewModel中針對這三部分定義三個viewModel,htm
function headViewModel(){
}
function mainViewModel(){
}
function footViewModel(){
}
而後在js加載時進行三部分的binding:
進行ko.applyBindings(new Cart(),document.getElementById("head"));
ko.applyBindings(new Cart(),document.getElementById("main"));
ko.applyBindings(new Cart(),document.getElementById("foot"));
時,通常不會報unable to process binding的錯誤。
可是若是你的viewModel中定義了這三部分head、main、foot,可是對應的html頁面裏缺乏head對應的block就會報標題中的錯誤了。
我按照knockout官網的文檔直接拷貝的js代碼以下:
1 <script type="text/javascript"> 2 function formatCurrency(value) { 3 return "$" + value.toFixed(2); 4 } 5 6 var CartLine = function() { 7 var self = this; 8 self.category = ko.observable(); 9 self.product = ko.observable(); 10 self.quantity = ko.observable(1); 11 self.subtotal = ko.computed(function() { 12 return self.product() ? self.product().price * parseInt("0" + self.quantity(), 10) : 0; 13 }); 14 15 // Whenever the category changes, reset the product selection 16 self.category.subscribe(function() { 17 self.product(undefined); 18 }); 19 }; 20 21 var Cart = function() { 22 // Stores an array of lines, and from these, can work out the grandTotal 23 var self = this; 24 self.lines = ko.observableArray([new CartLine()]); // Put one line in by default 25 self.grandTotal = ko.computed(function() { 26 var total = 0; 27 $.each(self.lines(), function() { total += this.subtotal() }) 28 return total; 29 }); 30 31 // Operations 32 self.addLine = function() { self.lines.push(new CartLine()) }; 33 self.removeLine = function(line) { self.lines.remove(line) }; 34 self.save = function() { 35 var dataToSave = $.map(self.lines(), function(line) { 36 return line.product() ? { 37 productName: line.product().name, 38 quantity: line.quantity() 39 } : undefined 40 }); 41 alert("Could now send this to server: " + JSON.stringify(dataToSave)); 42 }; 43 }; 44 45 ko.applyBindings(new Cart()); 46 </script>
html代碼以下:
<div class='liveExample' id="div1"> <table width='100%'> <thead> <tr> <th width='25%'>Category</th> <th width='25%'>Product</th> <th class='price' width='15%'>Price</th> <th class='quantity' width='10%'>Quantity</th> <th class='price' width='15%'>Subtotal</th> <th width='10%'> </th> </tr> </thead> <tbody data-bind='foreach: lines'> <tr> <td> <select data-bind='options: sampleProductCategories, optionsText: "name", optionsCaption: "Select...", value: category'> </select> </td> <td data-bind="with: category"> <select data-bind='options: products, optionsText: "name", optionsCaption: "Select...", value: $parent.product'> </select> </td> <td class='price' data-bind='with: product'> <span data-bind='text: formatCurrency(price)'> </span> </td> <td class='quantity'> <input data-bind='visible: product, value: quantity, valueUpdate: "afterkeydown"' /> </td> <td class='price'> <span data-bind='visible: product, text: formatCurrency(subtotal())' > </span> </td> <td> <a href='#' data-bind='click: $parent.removeLine'>Remove</a> </td> </tr> </tbody> </table> <p class='grandTotal'> Total value: <span data-bind='text: formatCurrency(grandTotal())'> </span> </p> <button data-bind='click: addLine'>Add product</button> <button data-bind='click: save'>Submit order</button> </div>
而後就報錯了:
Uncaught ReferenceError: Unable to process binding "value: function (){return category }"
Message: category is not defined
但是我上面明明定義了。
而後作了一下修改:
將js中的ko.applyBindings(new Cart());修改爲ko.applyBindings(new Cart(),document.getElementById("div1"));
就能夠了。
問題的緣由我尚未深究,可是我知道了在ko.applyBindings的時候,能夠養成一個加上banding範圍限制的習慣。