2015-01-21 122 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