2016-09-14 21 views
-2

我正在使用Node,Express和MongoDB運行一個站點。我在ajax調用之後生成容器以獲取數據以填充它們,並且每個容器都有一個按鈕,它使得另一個ajax調用特定於它正在獲取詳細信息的配方。第一次我做到了這一點,它完美的工作,但如果我得到第二個細節,它執行3次而不是一個的功能,如果我爲第三個容器執行它9次,等等。我對Jquery相當陌生,也許這是對事件如何工作的誤解。 saveRecipe函數也會出現問題。在我的js文件中按指數函數重複的函數

global.js

$(document).ajaxComplete(function(){ 
    $('.details').popover({"trigger": "manual", "html":"true"}); 
    $('.details').click(get_data_for_popover_and_display); 
    $('.save-favorite').on('click', saveRecipe); 
}); 

(function ($) { 
    $('#search').on('click', function (e) { 
     // remove resultset if this has already been run 
     $('.recipes').empty(); 

     var recipeName = document.getElementById('recipeName').value; 
     var recipeNameString = '&q=' + recipeName; 

     var ingredientHtml = '&allowedIngredient[]='; 
     var ingredientsArray = document.getElementById('ingredients').value.split(","); 
     var ingredientsString = ''; 
     if (ingredientsArray[0] !== ""){ 
     for (i = 0; i < ingredientsArray.length; i++){ 
      ingredientsArray[i] = ingredientHtml + ingredientsArray[i].trim(); 
     } 
     for (i = 0; i < ingredientsArray.length; i++){ 
      ingredientsString += ingredientsArray[i]; 
     } 
     } 

     var excludedIngredientHtml = '&excludedIngredient[]='; 
     var excludedIngredientsArray = document.getElementById('ingredientsExclude').value.split(","); 
     var excludedIngredientsString = ''; 
     if (excludedIngredientsArray[0] !== ""){ 
     for (i = 0; i < excludedIngredientsArray.length; i++){ 
      excludedIngredientsArray[i] = excludedIngredientHtml + excludedIngredientsArray[i].trim(); 
     } 
     for (i = 0; i < excludedIngredientsArray.length; i++){ 
      excludedIngredientsString += excludedIngredientsArray[i]; 
     } 
     } 

     var dietHtml = ''; 
     if(document.getElementById('lacto-veg').checked){ 
     dietHtml += '&allowedDiet[]=388^Lacto vegetarian'; 
     } 
     if(document.getElementById('ovo-veg').checked){ 
     dietHtml += '&allowedDiet[]=389^Ovo vegetarian'; 
     } 
     if(document.getElementById('paleo').checked){ 
     dietHtml += '&allowedDiet[]=403^Paleo'; 
     } 
     if(document.getElementById('pescetarian').checked){ 
     dietHtml += '&allowedDiet[]=390^Pescetarian'; 
     } 
     if(document.getElementById('vegan').checked){ 
     dietHtml += '&allowedDiet[]=386^vegan'; 
     } 
     if(document.getElementById('vegetarian').checked){ 
     dietHtml += '&allowedDiet[]=387^Lacto-ovo vegetarian'; 
     } 

     var allergyHtml = ''; 
     if(document.getElementById('dairy-free').checked){ 
     allergyHtml += '&allowedAllergy[]=396^Dairy-Free'; 
     } 
     if(document.getElementById('egg-free').checked){ 
     allergyHtml += '&allowedAllergy[]=397^Egg-Free'; 
     } 
     if(document.getElementById('gluten-free').checked){ 
     allergyHtml += '&allowedAllergy[]=393^gluten-Free'; 
     } 
     if(document.getElementById('peanut-free').checked){ 
     allergyHtml += '&allowedAllergy[]=394^Peanut-Free'; 
     } 
     if(document.getElementById('seafood-free').checked){ 
     allergyHtml += '&allowedAllergy[]=398^Seafood-Free'; 
     } 
     if(document.getElementById('seseme-free').checked){ 
     allergyHtml += '&allowedAllergy[]=399^Seseme-Free'; 
     } 
     if(document.getElementById('sulfite-free').checked){ 
     allergyHtml += '&allowedAllergy[]=401^Sulfite-Free'; 
     } 
     if(document.getElementById('tree-nut-free').checked){ 
     allergyHtml += '&allowedAllergy[]=395^Tree Nut-Free'; 
     } 
     if(document.getElementById('wheat-free').checked){ 
     allergyHtml += '&allowedAllergy[]=392^Wheat-Free'; 
     } 

     var apiHtml = 'http://api.yummly.com/v1/api/recipes?_app_id=&_app_key=' +recipeNameString; 
     if (ingredientsString){ 
     apiHtml += ingredientsString; 
     } 
     if (excludedIngredientsString){ 
     apiHtml += excludedIngredientsString; 
     } 
     if (dietHtml){ 
     apiHtml += dietHtml; 
     } 
     if (allergyHtml){ 
     apiHtml += allergyHtml; 
     } 
     apiHtml += '&requirePictures=true'; 
     apiHtml = apiHtml.replace(' ', '%20'); 

     $.getJSON(apiHtml, function (json) { 
     var recipes = [], 
      $recipes; 

     $.each(json, function (key, val) { 
      if (key === "matches"){ 
      for (i = 0; i < val.length ; i++) { 
       if (i%3 === 0){ 
       recipes.push('<div class="row">'); 
       } 
       recipes.push('<div class="col-sm-6 col-md-4">'); 
       recipes.push('<div class="thumbnail">' + '<img src="'+ val[i].imageUrlsBySize[90] + '" alt="' + val[i].recipeName + '" data-holder-rendered="true" style="height: 300px; width: 100%; display: block;"/>'); 
       recipes.push('<div class="caption">' + '<h3 class="caption-text">' + val[i].recipeName + '</h3>'); 
       recipes.push('<p class="caption-text">' + val[i].sourceDisplayName + '</p>'); 
       recipes.push('<p><button type="button" class="btn btn-primary details" data-toggle="popover" title="' + val[i].recipeName + '" value="' + val[i].id + '"> Details </button> '); 
       recipes.push('<button type="button" class="btn btn-primary save-favorite" method="post" action="saveFavorite" value="' + val[i].id + '"> Favorite </button></p>'); 
       recipes.push('</div></div></div>'); 
       if ((i+1)%3 === 0){ 
       recipes.push('</div>'); 
       } 
      } 
      } 
     }); 
     if (recipes.length < 1) { 
     recipes.push('<p>No results for parameters, try again!</p>'); 
     } 
     $recipes = $('<div />').appendTo('.recipes'); 
     $recipes.append(recipes.join('')); 
    }); 
    e.preventDefault(); 
    }); 
}(jQuery)); 


get_data_for_popover_and_display = function() { 
    var el = $(this); 
    if(el.hasClass('recipe-loaded')){ 
    } 
    else { 
    var _data = $(this).attr('alt'); 
    var recipeUrl = 'http://api.yummly.com/v1/api/recipe/' + this.value + '?_app_id=&_app_key='; 
    var recipeHtml = ''; 
    var ingredientsHtml = ''; 
    var nutritionHtml = ''; 
    var ratingHtml = ''; 
    var servingsHtml = ''; 
    var sourceHtml = ''; 

    $.getJSON(recipeUrl, function (json) { 
     $.each(json, function (key, val) { 
      if (key === "ingredientLines"){ 
      ingredientsHtml = '<h4>Ingredients:</h4><ul>'; 
      for (i = 0; i < val.length ; i++){ 
       ingredientsHtml += ('<li>' + val[i] + '</li>'); 
      } 
      ingredientsHtml += '</ul>'; 
      } 
      if (key === "nutritionEstimates"){ 
      if(val.length > 0){ 
      nutritionHtml = 'Cal. per Serving: ' + val[0].value + '<br>'; 
      } 
      } 
      if (key === "rating"){ 
      ratingHtml += 'Rating: ' + val + '</p>'; 
      } 
      if (key === "numberOfServings"){ 
      servingsHtml += '<p>Servings: ' + val + '<br>'; 
      } 
      if (key === "source"){ 
      sourceHtml += '<p><a type="button" class="btn btn-primary details" href="'+ val.sourceRecipeUrl +'" >Source</a>'; 
      } 
     }) 
     recipeHtml += ingredientsHtml; 
     recipeHtml += servingsHtml; 
     recipeHtml += nutritionHtml; 
     recipeHtml += ratingHtml; 
     recipeHtml += sourceHtml; 
     el.attr('data-content', recipeHtml).success(el.popover('toggle')); 
     el.addClass('recipe-loaded'); 
    }); 
    } 
}; 

function saveRecipe(){ 
    var recipeUrl = 'http://api.yummly.com/v1/api/recipe/' + this.value + '?_app_id=3e5b7dbe&_app_key=1d681685a57dac07e6df0b1c0df38de6'; 
    var json = $.getJSON(recipeUrl, function (data){ 
    console.log(JSON.stringify(data)); 
    $.ajax({ 
     type: 'POST', 
     data: data, 
     url: '/saverecipe', 
     dataType: 'JSON' 
    }); 
}); 
}; 
+1

嗨布拉德利,歡迎SO。在目前的狀態下,我會降低你的問題,因爲你只是傾銷大量的代碼,並要求我們解決你的問題。雖然你明顯可以做到這一點,甚至可能得到你想要的答案,但SO不是「免費代碼審查和錯誤修復站點」。請嘗試隔離您的問題,即您認爲哪些代碼的特定部分發生,您嘗試隔離和修復問題等。這將a)幫助其他人更快地幫助您,並且b)不承擔負擔理解我們其他人的所有代碼,這簡直是禮貌 – fresskoma

+0

感謝您的輸入fresskoma,我會盡量在未來更簡潔,因爲我可以縮小它到saveRecipe函數和$(文件).ajaxComplete(函數(){});一部分。 –

回答

0

這條線:

$('.details').click(get_data_for_popover_and_display); 

掛鉤了所有.detail元素事件處理程序將調用get_data_for_popover_and_display即使該元素已經有一個事件處理程序調用get_data_for_popover_and_display。同樣的,:

$('.save-favorite').on('click', saveRecipe); 

如此以來get_data_for_popover_and_display(至少)做另一個Ajax調用,這將增加另一種處理程序,你會得到隨着時間的推移不斷增加處理器的數量。

這正是像這樣:

function clickHandler() { 
 
    console.log(+new Date(), "Clicked"); 
 
    clickComplete(); 
 
} 
 
function clickComplete() { 
 
    $("#btn").on("click", clickHandler); 
 
} 
 
clickComplete();
<input type="button" id="btn" value="Click Me"> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

所以:只有當您尚未添加處理程序。也許是跟蹤在jQuery的data店:

function clickHandler() { 
 
    console.log(+new Date(), "Clicked"); 
 
    clickComplete(); 
 
} 
 
function clickComplete() { 
 
    $("#btn").filter(function() { 
 
    return !$(this).data("hasClick"); 
 
    }) 
 
    .on("click", clickHandler) 
 
    .data("hasClick", true); 
 
} 
 
clickComplete();
<input type="button" id="btn" value="Click Me"> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>