为什么我无法从Firebase数据库获取路径中的所有对象以做出反应?

时间:2018-07-13 20:09:28

标签: javascript reactjs firebase firebase-realtime-database

从一个屏幕移到另一个屏幕时,菜单必须完整显示。在这种情况下,它不会显示列表中的所有菜单(仅显示最新元素),刷新时会显示完整菜单。当我删除一个元素时,整个菜单也会折叠,只有最新的元素保留。在此处输入图像描述 enter image description here

请参见下面的代码

componentDidMount() {
  /* Create reference to messages in Firebase Database */

  this.setState({ ...this.state, messages: [] });

  let messagesRef = fire
    .database()
    .ref("vendor/" + this.state.Day + "/" + this.state.Vendor + "/dishname")
    .orderByKey()
    .limitToLast(100);
  messagesRef.on("child_added", snapshot => {
    /* Update React   state when message is added at Firebase Database */
    let message1 = { text: snapshot.val(), id: snapshot.key };
    console.log(this.state.messages);
    this.setState({
      ...this.state,
      messages: this.state.messages.concat(message1)
    });
  });
}

addMessage(e) {
  var newData = {
    Type: this.inputE3.value,
    Dish: this.inputEl.value,
    Price: this.inputE2.value
  };

  fire
    .database()
    .ref("vendor/" + this.state.Day + "/" + this.state.Vendor + "/dishname")
    .push(newData);

  this.inputEl.value = "";
  this.inputE2.value = "";
  this.inputE3.value = "";
  let messagesR = fire
    .database()
    .ref("vendor/" + this.state.Day + "/" + this.state.Vendor + "/dishname")
    .orderByKey()
    .limitToLast(100);
  messagesR.on("child_added", snapshot => {
    /* Update React   state when message is added at Firebase Database */
    let message1 = { text: snapshot.val(), id: snapshot.key };
    this.setState({
      ...this.state,
      messages: this.state.messages.concat(message1)
    });
  });
}

remove(id) {
  // console.log(this.state)
  let a = fire
    .database()
    .ref(
      "vendor/" + this.state.Day + "/" + this.state.Vendor + "/dishname/" + id
    );
  a.remove();
  this.setState({ ...this.state, messages: [] });
  //  this.componentDidMount();
}

render() {
  return (
    <div>
      <form onSubmit={this.addMessage.bind(this)}>
        <input
          className="gocenter"
          id="one"
          type="text"
          ref={e3 => (this.inputE3 = e3)}
          placeholder="Veg or Non-Veg"
        />
        <input
          className="gocenter"
          id="one"
          type="text"
          ref={el => (this.inputEl = el)}
          placeholder="Enter the dish-name"
        />
        <input
          className="gocenter"
          id="one"
          type="text"
          ref={e2 => (this.inputE2 = e2)}
          placeholder="Enter the price"
        />
        <input className="submit" type="submit" value="Add Menu" />
        <br />
        <p id="oneline">
          {" "}
          <div id="one">Type </div>
          <div id="one"> Dish </div>
          <div id="one"> Price </div>
        </p>
      </form>

      <ul>
        {this.state.messages
          ? this.state.messages.map(message1 => (
              <li id="oneline" key={message1.id}>
                <div id="one">{message1.text.Type} </div>
                <div id="one"> {message1.text.Dish} </div>
                <div id="one"> {message1.text.Price}</div>{" "}
                <Button
                  className="submit"
                  onClick={this.remove.bind(this, message1.id)}
                >
                  Remove
                </Button>
              </li>
            ))
          : null}
      </ul>
    </div>
  );
}

2 个答案:

答案 0 :(得分:2)

请记住,<style> .categoryButtonSelected{background-color: #1c71b9 !important; color: white !important;} .headertitle{text-align: center; margin: 0; padding: 0;} </style> <?php require_once('database.php'); if ($result = $mysqli->query("SELECT t.*, GROUP_CONCAT(c.category) categories, GROUP_CONCAT(k.keyword) keywords FROM dataclayTemplates t LEFT JOIN dataclayCategoryLink cl JOIN dataclayCategories c ON cl.categoryId=c.id ON t.id=cl.templateId LEFT JOIN dataclayKeywordLink kl JOIN dataclayKeywords k ON kl.keywordId=k.id ON t.id=kl.templateId GROUP BY t.id")) { while($row = $result->fetch_array(MYSQL_ASSOC)) { if($row["categories"] == null) { $row["categoryArray"] = []; } else { $row["categoryArray"] = array_unique(explode(",",$row["categories"])); } unset($row["categories"]); if($row["keywords"] == null) { $row["keywordArray"] = []; } else { $row["keywordArray"] = array_unique(explode(",",$row["keywords"])); } unset($row["keywords"]); $templateArray[] = $row; } } $result->close(); $categoryArray = array(); if ($result = $mysqli->query("SELECT category FROM creative_engine.dataclayCategories;")) { while($row = $result->fetch_array(MYSQL_ASSOC)) { array_push($categoryArray, $row['category']); } } $result->close(); $keywordArray = array(); if ($result = $mysqli->query("SELECT keyword FROM creative_engine.dataclayKeywords;")) { while($row = $result->fetch_array(MYSQL_ASSOC)) { array_push($keywordArray, $row['keyword']); } } $result->close(); $mysqli->close(); include('header.php'); ?> <div v-cloak id="templates" class="container content"> <div class="col-md-3 visible-lg-block hidden-md"> <form role="form"> <div class="form-group"> <label for="searchBar">Search</label> <input v-model="searchquery" type="text" placeholder="Search Tempates" id="searchBar" autocomplete="off" class="form-control"> </div> <div class="form-group"> <label>Sort By</label> <select v-model="sortBy" class="form-control"> <option value="renderTime">Render Time</option> <option value="az">A-Z</option> <option value="dateAdded">Newest</option> </select> </div> <div class="form-group"> <h5>Categories</h5> <div v-for="category in categories" :id="category + 'Button'" v-on:click.prevent="selectCategory(category)" class="btn btn-default categoryButton"> {{category}} </div> </div> <div class="form-group"> <h5>Keywords</h5> <div v-for="keyword in keywords" :id="keyword + 'Button'" v-on:click.prevent="selectKeyword(keyword)" class="btn btn-default categoryButton"> {{keyword}} </div> </div> </form> </div><!--end lg template menu--> <!--search templates modal--> <div class="modal fade" role="dialog" id="searchTemplatesModal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">X</button> <h2 class="modal-title">Search Templates</h2> <!--end .modal-title--> </div> <!--end modal-header--> <div class="modal-body"> <form role="form"> <div class="form-group"> <label>Search</label> <input v-model="searchquery" type="text" placeholder="Search Tempates" autocomplete="off" class="form-control"> </div> <!--.end searchquery--> <div class="form-group"> <label>Sort By</label> <select v-model="sortBy" class="form-control"> <option value="renderTime">Render Time</option> <option value="az">A-Z</option> <option value="dateAdded">Newest</option> </select> </div> <!--end sortBy--> <div class="form-group"> <h5>Categories</h5> <div v-for="category in categories" :id="category + 'Button'" v-on:click.prevent="selectCategory(category)" class="btn btn-default categoryButton"> {{category}} </div> </div> <!--end categorys--> <div class="form-group"> <h5>Keywords</h5> <div v-for="keyword in keywords" :id="keyword + 'Button'" v-on:click.prevent="selectKeyword(keyword)" class="btn btn-default categoryButton"> {{keyword}} </div> </div> <!--end keywords--> </form> </div> <!--end .modal-body--> <div class="modal-footer"> <button type="button" class="btn btn-primary btn-block" data-dismiss="modal">Search</button> </div><!--end .modal-footer--> </div> <!--end .modal-content--> </div> <!--end .modal-dialog--> </div> <!-- end search templates modal--> <div class="col-md-9"> <div class="row"><h1 class="headertitle">Creative Engine Templates</h1></div> <div class="row"><div class="hidden-lg visible-md visible-sm visible-xs pull-left btn btn-primary" data-target="#searchTemplatesModal" data-toggle="modal"><span class="fa fa-search"></span> Search Templates</div></div> <div class="row"> <div v-cloak v-bind:key="template.itemId + '_' + index" v-for="(template, index) in searchResults" class="col-md-4"> <div class="card"> <video muted :src="'CreativeEngine/'+template.itemId+'/'+template.thumbName+'.mp4'" controls preload="none" controlsList="nodownload nofullscreen" :poster="'CreativeEngine/'+template.itemId+'/'+template.thumbName+'.jpg'" loop="loop"></video> <div class="card-body"> <p class="card-title">{{template.itemName}}</p><!--end card-title--> <p v-show="displaycount==0" class="card-text">Please create a display to customize</p><!--end user has no display card-text--> <p v-show="displaycount>0" class="card-text">Custom Text, Custom Colors, Upload Logo</p><!--end user has display card text--> <p class="card-text">{{template.renderTime}} minutes</p> <a href="#" v-show="loggedin==1 && displaycount>0" class="btn btn-primary btn-block">Customize</a><!--logged in and has display button--> <a href="#" v-show="loggedin==0" class="btn btn-primary btn-block" disabled>Customize</a><!--not logged in button--> <a href="getCustomer.php?showAddDisplayForm=1" v-show="loggedin==1 && displaycount==0" class="btn btn-primary btn-block">Create A Display</a> </div><!--end card-body--> </div><!--end card--> </div><!-- end col-md-4--> </div><!--end row--> </div><!--end col-md-9--> </div><!--end templates app--> <script> var app = new Vue({ el: '#templates', data: { loggedin:'', displaycount:'<?php if(isset($_SESSION['displaycount'])){echo $_SESSION['displaycount'];} else{echo 0;}?>', searchquery:'', templateArray: <?php echo json_encode($templateArray); ?>, filteredTemplateArray: <?php echo json_encode($templateArray); ?>, categories: <?php echo json_encode($categoryArray); ?>, selectedCategories: [], keywords: <?php echo json_encode($keywordArray); ?>, selectedKeywords: [], sortBy: '' }, computed: { searchResults: function(){ return this.filteredTemplateArray.filter((template)=>{ return template.itemName.toLowerCase().includes(this.searchquery.toLowerCase()); }) } }, created: function() { this.loggedin=<?php if(isset($_SESSION['loggedin'])){echo $_SESSION['loggedin'];} else {echo 0;}?>; this.filteredTemplateArray.sort(function(a,b) { return parseInt(a.renderTime) - parseInt(b.renderTime); }); }, watch: { sortBy: function() { if(this.sortBy == "az") { this.filteredTemplateArray.sort(function(a,b) { if(a.itemName > b.itemName) { return 1; } if(a.itemName < b.itemName) { return -1; } return 0; }); } if(this.sortBy == "dateAdded") { this.filteredTemplateArray.sort(function(a,b) { if(a.dateAdded < b.dateAdded) { return 1; } if(a.dateAdded > b.dateAdded) { return -1; } return 0; }); } if(this.sortBy == "renderTime") { this.filteredTemplateArray.sort(function(a,b) { return parseInt(a.renderTime) - parseInt(b.renderTime); }); } } }, mounted: function(){ this.sortBy="renderTime"; }, methods: { filter: function() { var filteredCategoryArray = []; var filteredKeywordArray = []; if(this.selectedCategories.length != 0) { for(var i = 0; i < this.templateArray.length; i++) { for(var j = 0; j < this.selectedCategories.length; j++ ) { for(var k = 0; k < this.templateArray[i].categoryArray.length; k++ ) { if(this.templateArray[i].categoryArray[k] == this.selectedCategories[j]) { var arrayDuplicate = false; for(var l = 0; l < filteredKeywordArray.length; l++) { if(filteredCategoryArray[l].id == this.templateArray[i].id) { arrayDuplicate = true; } } if(arrayDuplicate == false) { filteredCategoryArray.push(this.templateArray[i]); } } } } } } else { for(var i = 0; i < this.templateArray.length; i++){ filteredCategoryArray.push(this.templateArray[i]); } } if(this.selectedKeywords.length != 0) { for(var i = 0; i < filteredCategoryArray.length; i++) { for(var j = 0; j < this.selectedKeywords.length; j++ ) { for(var k = 0; k < filteredCategoryArray[i].keywordArray.length; k++ ) { if(filteredCategoryArray[i].keywordArray[k] == this.selectedKeywords[j]) { var arrayDuplicate = false; for(var l = 0; l < filteredKeywordArray.length; l++) { if(filteredKeywordArray[l].id == filteredCategoryArray[i].id) { arrayDuplicate = true; } } if(arrayDuplicate == false) { filteredKeywordArray.push(filteredCategoryArray[i]); } } } } } } else { for(var i = 0; i < filteredCategoryArray.length; i++){ filteredKeywordArray.push(filteredCategoryArray[i]); } } if(this.sortBy == "az") { filteredKeywordArray.sort(function(a,b) { if(a.itemName > b.itemName) { return 1; } if(a.itemName < b.itemName) { return -1; } return 0; }); } if(this.sortBy == "dateAdded") { filteredKeywordArray.sort(function(a,b) { if(a.dateAdded < b.dateAdded) { return 1; } if(a.dateAdded > b.dateAdded) { return -1; } return 0; }); } if(this.sortBy == "renderTime") { filteredKeywordArray.sort(function(a,b) { return parseInt(a.renderTime) - parseInt(b.renderTime); }); } this.filteredTemplateArray = filteredKeywordArray; $('html,body').scrollTop(0); }, selectCategory: function(category) { var categoryButton = $('#' + category + 'Button'); categoryButton.toggleClass('categoryButtonSelected'); if(this.selectedCategories.includes(category)){ var array = []; for(var i = 0; i < this.selectedCategories.length; i++) { if(this.selectedCategories[i] != category) { array.push(this.selectedCategories[i]); } } this.selectedCategories = array; } else { this.selectedCategories.push(category); } this.filter(); }, selectKeyword: function(keyword) { var categoryButton = $('#' + keyword + 'Button'); categoryButton.toggleClass('categoryButtonSelected'); if(this.selectedKeywords.includes(keyword)){ var array = []; for(var i = 0; i < this.selectedKeywords.length; i++) { if(this.selectedKeywords[i] != keyword) { array.push(this.selectedKeywords[i]); } } this.selectedKeywords = array; } else { this.selectedKeywords.push(keyword); } this.filter(); } } }); </script> 是一个异步任务,因此由于竞态条件和状态被覆盖,您的代码可能无法正常工作。

因此,您可以将逻辑封装在这样的函数中:

setState()

,然后使用loadData() { const messagesRef = fire .database() .ref("vendor/" + this.state.Day + "/" + this.state.Vendor + "/dishname") .orderByKey() .limitToLast(100); messagesRef.on("child_added", snapshot => { const message1 = { text: snapshot.val(), id: snapshot.key }; console.log(this.state.messages); this.setState({ // ...this.state, <-- You can ommit this, as you are only interested in // setting the messages property messages: this.state.messages.concat(message1) }); }); } 回调功能在componentDidMount中调用它:

setState

答案 1 :(得分:1)

您在删除功能中设置了<div id="container3"></div> <input type="button" value="add" onclick="addDay();"> <input type="button" value="remove" onclick="removeDay();">