无法读取undefined的属性'bind'

时间:2015-10-08 09:45:04

标签: javascript jquery reactjs

我正在尝试创建一个购物车,在此我试图通过在购物车中添加一个带项目的添加按钮来调用ajax post功能。在我的下面的购物车功能代码中,如果我删除了onclinck函数的这一行

onClick={ this.createNeworder.bind( this, this.orderid, this.item.product_code)}> Add </a> </span> , 

或只添加一个简单的按钮,它会在购物车中显示项目和按钮。但是如果我添加这行代码,那么它会给出错误Cannot read property 'bind' of undefined,并且不会在购物车中添加任何项目。我在其他页面代码中使用了相同的onclick函数,它正在工作,但我不知道它为什么不在这里工作。

var orderid = document.getElementById('bizorderid').innerHTML;
console.log(orderid);

function testAjax() {
return $.ajax({
            type: 'GET',
            url: "/restaurant/menu/list/100/1",
            headers: {
                                    Accept : "application/json",
                                                 "Content-Type":   "application/json"
                    },
            async : false
            }).done( function(json) {
                    //tata = json;

//                      console.log(json);
                    return json;
            }).responseText;

            }

  var dt = testAjax();
  var productsCollection = JSON.parse(dt);
  //var promise = $.parseJSON(pt);
  console.log(productsCollection)

/** @jsx React.DOM */

var Product = React.createClass({
getInitialState: function() {
  return {
    added: false
  };
},

addToCart: function(e) {
  if(!this.state.added) {
    // add
    $.publish('cart.added', this.props.data);
  }
  else {
    // remove
    $.publish('cart.removed', this.props.data.id);
  }

  this.setState({
    added: !this.state.added
  });
},

render: function() {
    // assign to props
    var data = this.props.data;

return (
      <div className="card">
        <div className="title">
          <h3><a>{data.product_name}</a></h3> </div>
          <div className="content">Price :{data.price}  <br />category : {data.groupid} <br />
                    Units: {data.unit} <br /> Code : {data.product_code} <br />
            <button className={this.state.added ? 'button  success' : 'button small radius'} onClick={this.addToCart}>
              {this.state.added ? 'Remove' : 'Add to cart'}
            </button>
        </div>
            </div>
          );
      }
  });


  /** @jsx React.DOM */

  var ProductsList = React.createClass({
      render: function() {

          var products = this.props.data.map(function(product) {
              return (
                <li key={product.product_code}>
                  <Product data={product} />
                </li>
              )
          });

          return (
            <ul className="clearfix">
              {products}
            </ul>
          );
      }
  });

  var Cart = React.createClass({

  createNeworder: function(orderid, product_code) {
                                      //var tbn = this.iid;
                                     // var tbn = iid;
                                var o_id = orderid;
                                console.log(o_id);
                                var p_code = product_code;
                                var unit = 1;
                                      $.ajax({
                                                url: '/restaurant/order/product/'+o_id+'/'+p_code+'/'+unit,
                                                type: 'POST',
                                                headers: {
                                                            // Accept : "application/json",
                                                             "Content-Type": "application/json"
                                                          },

                                                success: function(data) {
  //                                              console.log(data.orderid);
                                                  var orderid = data.orderid;
                                                  console.log(orderid);

                                                //  window.location = '/diner/orderdiner/'+orderid;

                                                  this.setState({data: data});
                                                        }.bind(this),
                                                error: function(xhr, status, err) {
                                       //   console.error(this.props.url, status, err.toString());
                                                        }.bind(this)
                                                      });
                                    },


  getInitialState: function() {
        // also subscribe to product events here
        $.subscribe('cart.added', this.addItem);
        $.subscribe('cart.removed', this.removeItem);

        return {
          items: [],
          total: 0,
          currency: 'EUR'
        };
      },

      addItem: function(e, item) {
        this.state.items.push(item);
        this.forceUpdate();

        this.countTotal();
      },

      removeItem: function(e, itemId) {
        var itemIndexInArray;

        this.state.items.some(function(item, index) {
          if(item.id === itemId) {
            itemIndexInArray = index;
            return true;
          }
        });

        this.state.items.splice(itemIndexInArray, 1);
        this.forceUpdate();

        this.countTotal();
      },

   countTotal: function() {
        var total = 0;

        this.state.items.forEach(function(item, index) {
          total += item.price;
        });

        this.setState({
          total: total
        })
      },

      render: function() {

          var items = this.state.items.map(function(item) {
            //      var pro_code = {item.product_code} ;
    //              console.log(pro_code);
              return (
                <li key={item.id} className="cart-item">
                  <span className="cart-item__name">{item.product_name}</span>
                  <span className="cart-item__price">{item.price} {item.currency}</span>
                  <span hidden className="cart-item__price">{item.product_code} {item.currency}</span>
            <span > <a onClick={ this.createNeworder.bind( this, this.orderid, this.item.product_code)} > Add </a> </span>
                </li>
              )
          });

          var body = (
            <ul>
              {items}
            </ul>
          );

          var empty = <div className="alert alert-info">Cart is empty</div>;

            return (
            <div className="panel panel-default">
              <div className="panel-body">
                {items.length > 0 ? body : empty}
              </div>
            </div>
          );
      }
  });


  React.render(<ProductsList data={productsCollection} />, document.getElementById('tabmenu'));
        React.render(<Cart />, document.getElementById('cart'));

1 个答案:

答案 0 :(得分:4)

React允许您将子组件中的数据传递回其父组件。我们通过将新回调(一些自定义回调)传递给子进程,将其绑定到子进程(单击/任何其他)事件,在父进程方法中执行此操作。每当触发事件时,都将调用回调。

我看到您正在关联onclick的回调,因此您需要通过执行类似

的操作来包装整个items数组,这是map的结果
this.state.items.map(function(item) {
return (
   // binding of child's event
)}.bind(this);

其中this将是您的cart

的实例

来源:React Documentation