将json附加到DOM元素数组

时间:2017-05-13 07:22:52

标签: javascript jquery json ajax

我正在制作一个包含食谱的网站,我通过Mustache.js模板从json文件加载它们。 我的json看起来像这样:

{
"recipes":[
{"name": "A", preparationTime: "40min", "servings": "3", "image": "path/to/imageA"},
{"name": "B", preparationTime: "30min", "servings": "2", "image": "path/to/imageB"},
{"name": "C", preparationTime: "20min", "servings": "3", "image": "path/to/imageC"},
{"name": "D", preparationTime: "30min", "servings": "4", "image": "path/to/imageD"}
]
}

我的模板如下所示:

var recipeTemplate = "" +
"<div class='col-6 recipeUnit'>" +
"<div class='recipeItem row'>" + 
"<div class='recipeItem__image col-5'><img src='{{image}}' alt='recipe image'></div>" +
"<div class='recipeItem__description col-7'>" + 
"<h3 class='recipeTitle'>{{name}}</h3>" + 
"<div class='details'>" +
"<span>{{preparationTime}}</span>" +
"<span>{{servings}}</span>" +
"</div>" +
"<a class='buttonDetails' href='#'>see more</a>" +
"</div>" +
"</div>" +
"</div>";

我的ajax加载函数如下所示:

$(document).ready(function(){

    loadRecipes()
    function loadRecipes(){

        $.ajax({

            type: "GET",
            url: "recipes.json", 
            dataType: "JSON",
            cache: false,
            success: function(data){
            $section.empty();
            for(var i = 0; i < data.recipes.length; i++){

                var recipe = data.recipes[i];
                var html = Mustache.to_html(recipeTemplate, recipe);
                $section.append(html);
                $button = $(".buttonDetails");
                $button.data.recipe = recipe;

            };

            $button.on("click", function(){

                console.log($(this).data.recipe)
                return false;


            }); 

        });

    }

})

我希望能够将每个特定配方的json存储到页面上显示的每个配方的$按钮中。一切正常,但是当我想在我点击按钮时调试data.log data.recipe属性我总是从json获取最后一个数组项。我一直在努力解决这个问题很长一段时间,我不明白为什么它会显示最后一项。 最初我在这里接受了telez的想法: Best practices for Storing JSON in DOM。 如果有人能向我解释为什么会出现这个问题以及我该如何解决它,我将不胜感激。

3 个答案:

答案 0 :(得分:0)

因为nc remotehost 3306匹配到该点之前附加到文档的所有按钮。所以基本上你迭代所有食谱并将最后的收据数据设置为每个食谱的所有按钮。这使您可以将所有按钮数据设置为最后一个配方。

答案 1 :(得分:0)

问题在于:

$button = $(".buttonDetails");

您可以获得全部按钮,并立即为所有按钮指定配方。 为避免这种情况,您应该更改选择器,使其仅搜索当前模板。

答案 2 :(得分:0)

这里有几个问题。

  1. 每次迭代都会重新分配您对$button的引用,因此当您点击$按钮时,它会指向最后一个被绑定的按钮。

  2. 由于您的$按钮正在重新分配,因此与其关联的数据也将被重新分配。

  3. Please see this fiddle

    $(document).ready(function(){
        var $section = $('section');
        loadRecipes();
        function loadRecipes(){
    
                var solution = [];
    
                for(var i = 0; i < data.recipes.length; i++){
                    var $button;
                    var recipe = data.recipes[i];
                    var html = Mustache.to_html(recipeTemplate, recipe);
                    $section.append(html);
                    $button = $(".recipeUnit:last .buttonDetails"); // get the last $button every time...
                    $button.data.recipe = recipe;
    
                    // capture each $button and store it in array. By doing so we ensure we don't reasign the button.
                                    solution[i] = $button;   
                    solution[i].data('recipe',recipe);
               };
    
             // $button here is going to be the D button, because $button is assigned 4 times.
              $button.on("click",function(){
                   console.log('This is wrong, because the $button variable is repointed on every iteration',$(this).data.recipe);
                     return false;
               });  
    
              // here we have really do have 4 different buttons...
              solution.map(function($button){
                $button.on('click',function(e){
                                console.log($(this).data().recipe);
                });
              });
         }
    
    })