2015-01-21 204 views
0

請耐心等待,因爲我只是剛剛進入JavaScript,我是全新的OOP的Javascript,所以...有人可以幫我解決我的問題嗎? (原諒我在碼的長度和註釋)按鈕onClick不會正常工作

要啓動:我已創建2個對象:產品,籃 表被載經由所創建的「createProductRows()」功能傳遞產品的陣列對象。這會打印出產品信息並創建一個按鈕,將產品添加到購物籃中。它的按鈕(或者別的什麼)給了我這個問題。 *我希望按鈕調用addProduct()函數,並使用productList數組中的產品索引,該數組又調用2個函數; addToBasket()和display()在Basket對象中。這應該將創建的元素添加到購物籃表

我不確定是否正確傳入productList數組,或者我應該使用Basket的原型方法,任何幫助得到這個正常工作將不勝感激。由於

var productList = []; // array where product objects are to be held 
var basket; 
var obj; 

//product constructor 
var Product = function(name, description, quantity, price, gender) { 
    obj = this; // a reference to this object //could use 
    this.name = name; 
    this.description = description; 
    this.quantity = quantity; 
    this.price = price.toFixed(2); 
    this.gender = gender; 
}; 
    //product prototypes 
    Product.prototype = { 
     toString: function() { return this.name.toLowerCase(); } 
    }; 
    Product.prototype.getPrice = function() { 
     return '\u00A3' + this.price; 
    }; 
    Product.prototype.getQuantity = function() { 
     return this.quantity; 
    }; 

//instantiate new products 
var shorts = new Product('Shorts', 'Stone Wash Demin Shorts', 20, 25.90, 'F'); 
var bag = new Product('Bag', 'Leather Shoulder Bag', 4, 50.45, 'F'); 
var blouse = new Product('Blouse', 'Vintage Blue Silk Polka Dot Blouse', 8, 45.99, 'F'); 
var boots = new Product('Boots', 'Soft Leather Brown Ankle Boots', 3, 65.35, 'F'); 
var belts = new Product('Belts', 'Woven Finish Fashion Belt', 15, 21.99, 'F'); 
var shirt = new Product('Shirt', 'Jacquard Pattern Wrangler Western Shirt', 19, 34.87, 'M'); 
var shoes = new Product('Shoes', 'Suede Ankle Boots', 6, 55.00, 'M'); 
var trousers = new Product('Trousers', 'Izod Peach Chinos', 23, 31.75, 'M'); 
var belt = new Product('Belt', 'Suede Casual Belt', 4, 22.98, 'M'); 
var hat = new Product('Hat', 'Trilby Style Brown Woven Fix', 2, 67.80, 'M'); 

//push all product objects to an array 
productList.push(shorts, bag, blouse, boots, belts, shirt, shoes, trousers, belt, hat); 

// basket constructor 
var Basket = function(container, products) { // passes in the product list 
    this.container = container; // this tells me where to add the data 
    this.products = products; //reference to product values 
    this.quantity = []; // stores quantities in bag 

    for (var i=0; i < products.length; i++) { //find product 

     this.quantity[i] = 0; //amount of each product in basket 

     // method to add to basket 
     this.addToBasket = function(index) { //reference to the product to add 
      this.quantity[index]++; 
      this.products[i].quantity--; // minus one from the products list 
     }; 

     // method to remove from basket 
     this.removeFromBasket = function(index) { 
      if (this.quantity[index] > 0) 
       this.quantity[index]--; 
       this.products[i].quantity++; 
     }; 

     //displays product 
     this.display = function() { 
      for (var i=0; i < this.quantity.length; i++) { 
       if (this.quantity[i] > 0) { 
        var tbl = this.container 
        var row = tbl.insertRow(tbl.rows.length); // create a row element to append cells to 

        var total_price = this.quantity[i] * this.products[i].price; 
        //cell values 
        var desc = this.products[i].description; //for each value add new cell 
        var qty = this.quantity[i] 
        var price = this.products[i].price; 
        var total = total_price; 
        var remove = createRemoveBtn(); 

        var cell = tbl.rows[i].insertCell(-1); // add a new cell, inserted at end of each row 
        //append cells 
        cell.appendChild(desc); 
        cell.appendChild(qty); 
        cell.appendChild(price); 
        cell.appendChild(total); 
        cell.appendChild(remove); 
        tbl.appendChild(row); // finally append the rows to the table 

        function createRemoveBtn() { 
         var btn = document.createElement('input'); 
         var buttonName = products[i].name.toUpperCase(); 
         btn.type = 'button'; 
         btn.value = 'Remove'; 
         btn.id = buttonName[i]; //append button names from object name 
         btn.onclick = function() {removeProduct(i);}; //test 
        return btn; 
        };//end function 'createRemoveBtn()' 
       };//end if 'quantity' 
      };//end for 'basket' 
     };//end function 'this.display()' 
    };//end for 'products' 
};//end Object 'Basket' 

//create a new instance of the Basket object 
basket = new Basket(document.getElementById('basketTable').getElementsByTagName('tbody')[0], productList); // *** need to create a new container for the basket 

//button functions 
function addProduct(item) { //add to basket function 
    basket.addToBasket(item); 
    basket.display(); 
    alert(productList[item].name + ' added to basket'); 
} 
function removeProduct(item) { //remove item from basket 
    basket.removeFromBasket(item); 
    basket.display(); 
    alert(productList[item].name + ' removed to basket'); 
} 

//displays product table which is called on the body onload event 
function createProductRows(products) { // passing in productList[] 

    var tbl = document.getElementById('productTable').getElementsByTagName('tbody')[0]; // reference to the table to add rows to in the table body 
    for (var i=0; i < products.length; i++) { // index the productsList (iterate through 0-9) 

     var myProduct = products[i]; // keep a reference to each individual product - shorts, bag, blouse, etc... 
     var myRow = tbl.insertRow(tbl.rows.length); // create a row element to append cells to 
     var myProperties = ['name', 'description', 'quantity', 'price', 'gender']; //store the property names of the products, references to the object data 

     for (var j=0; j < myProperties.length; j++) // for each property in myProperties [0-4] 
     { 
      var myCell = myRow.insertCell(j); //create table cell element 
      var data = myProduct[myProperties[j]]; // store property values of products 
      var node = document.createTextNode(data); //add the data to a text node 
      myCell.appendChild(node); // append text node to table cell 
      myRow.appendChild(myCell); // add to end of the row 
     } 

     var newCell = tbl.rows[i].insertCell(-1); // create a new cell, inserted at end of each row 
     newCell.appendChild(createAddBtn()); // add buttons to cells 
     tbl.appendChild(myRow); // finally append the rows to the table 

     function createAddBtn() { 
      var btn = document.createElement('input'); 
      var buttonName = products[i].name.toLowerCase(); // to be added to the button's id value 
      btn.type = 'button'; 
      btn.value = 'Add'; 
      btn.id = buttonName; //append button names from object name 
      btn.onclick = function() {addProduct(i);}; 
      return btn; 
     }; 
    }; 
}; 
+2

你還沒有真正解釋實際問題是什麼。按鈕有什麼問題?此外,如果您可以嘗試將代碼減少到最低限度的示例(請參閱https://stackoverflow.com/help/mcve幫助創建一個很好的問題) – 2015-01-21 03:25:44

+0

不是你在問什麼,但要注意你不要因爲再次使用它們的唯一地方就是添加到'productList'數組中:只需將新產品直接添加到數組中就可以了 - 'productList.push(新產品('Shorts','Stone Wash Demin Shorts',20,25.90,'F'));' – nnnnnn 2015-01-21 03:28:05

+0

你在哪裏追加動態創建的輸入類型按鈕? – 2015-01-21 03:34:35

回答

0

[更新]

在你的情況下,問題可能出在你的方式創建封閉:

btn.onclick = function() {addProduct(i);}; 

你可以嘗試登錄,並檢查了控制檯看看我的價值是:

btn.onclick = function() {console.log('and i is:',i);addProduct(i);}; 

當創建在循環i的值是不是你認爲它是關閉,你也許可以通過使用IIFE解決它:

btn.onclick = (function(index) { 
    return function(){ 
    console.log('and index is:',index); 
    addProduct(index); 
    }; 
}(i)); 

問題的設置事件處理程序是你拿錯調用對象。

這裏是約調用對象以下answer副本:

this變量

在所有的示例代碼,你會看到這指的是當前實例。

這個變量實際上指的是調用對象,它指的是函數前面的對象。

爲了澄清見下面的代碼:

theInvokingObject.thefunction(); 

其中這將參考錯誤的對象的情況下通常是附着事件偵聽器,回調或超時和間隔時。在接下來的兩行代碼中,我們傳遞函數,我們不調用它。傳遞函數是:someObject.aFunction並調用它:someObject.aFunction()。這個值並不是指函數被聲明的對象,而是指向調用它的對象。

setTimeout(someObject.aFuncton,100);//this in aFunction is window 
somebutton.onclick = someObject.aFunction;//this in aFunction is somebutton 

爲了使這個在上述情況下是指someObject你可以通過一個封閉而不是直接的功能:

setTimeout(function(){someObject.aFuncton();},100); 
somebutton.onclick = function(){someObject.aFunction();}; 
+0

好吧我現在可以看到索引..但是你能告訴我哪裏出錯了,關於用籃子構造函數中指定的數據設置行數據。它似乎沒有從中讀取產品數據。 – user3414871 2015-01-21 05:01:08

+0

籃子構造函數中的display()函數應該創建要插入籃子的行 – user3414871 2015-01-21 05:04:02

+0

也仍然學習參數傳遞,這樣的noob – user3414871 2015-01-21 05:05:40