Javascript 无法读取未定义的属性“绑定”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33012165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:30:48  来源:igfitidea点击:

Cannot read property 'bind' of undefined

javascriptjqueryreactjs

提问by Amit Bondwal

I am trying to create a cart, In this I am trying to call an ajax post function, by putting an add button in cart with item. In my below code in cart function, if I remove this line of onclinckfunction

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

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

or add just a simple button, it show the item and button in cart. But if I add this line of code then it gives the error Cannot read property 'bind' of undefinedand don't add any item in cart. I have used same onclickfunction in other page code and It is working but I don't know why it is not working here.

或者只添加一个简单的按钮,它会显示购物车中的项目和按钮。但是,如果我添加这行代码,则会出现错误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'));

回答by sujay

React lets you pass data from the child component back up to its parent. We do this in the parent's render method by passing a new callback (some custom callback) into the child, binding it to the child's (click/any other) event. Whenever the event is triggered, the callback will be invoked.

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

I see that you are associating the callback for an onclick and hence you need to wrap the whole itemsarray which is the result of mapby doing something like

我看到您正在为 onclick 关联回调,因此您需要包装整个items数组,这是map通过执行类似操作的结果

this.state.items.map(function(item) {
return (
   // binding of child's event
)}.bind(this);

where thiswill be instance of your cartclass

this你的cart班级的实例在哪里

source: React Documentation

来源:React 文档