2016-09-25 4 views
1

application.jsでは、私はすべての 'トピック'をajax呼び出しのページにコンパイルしておき、クリックするとすべての情報が画面に表示されます。すべての開発で素晴らしい作品が、私は500サーバーのエラーが発生します。なぜ、console.logは20回ではなく1回だけ機能しますか?

これをデバッグしようとすると、コンソールが.onclick呼び出しで20回ロギングしていることがわかりました。なぜこれが起こっているのですか?生産(英雄)で500エラーが返されている理由は何ですか?

私はこの問題が発生している3つのconsole.logの周りに** **を付けます。

var listingSource = $("#listingTopics").html(); 
var compiledTopics = Handlebars.compile(listingSource); 

トピックハンドルテンプレート:事前に

<script id="listingTopics"> 
    <div> 
    <a href={{link}} class="listing-topics">{{title}}</a> 
    </div> 
</script> 

おかげ同じJSファイルの一番下に

if(window.location.pathname === "/topics") { 
    $('.actions').click(function(e) { 
     console.log("submit"); 
    }) 

    $.ajax({ 
      url: '/topics', 
      dataType: 'json', 
      type: 'GET', 
      success: function(result) { 
       console.log(result); 
       for(var i = 0; i < result.length; i++) { 
        var title = result[i].title; 
        var level = result[i].level; 
        var id = result[i].id; 
        var favlink = '/topics/' + id + '/favorite';  
        var link = '/topics/' + id; 
        var topicInfo = {title: title, link: link}; 
        var template = compiledTopics(topicInfo); 
        $('.topic-wrapper').append(template); 



       $('.listing-topics, .favorite-topic-title').click(function(e){ 
         e.preventDefault(); 
         if($(this).hasClass("favorite-topic-title")) { 
          var heartClass = "favorited_heart_icon" 

         } 
         else if($(this).hasClass("listing-topics")) { 
          var heartClass = "unfavorited_heart_icon"; 
          $('html, body').animate({ scrollTop: 0 }, 'fast'); 

         } 
         **console.log(this);** 
         $.ajax({ 
          url: this, 
          dataType: "json", 
          type: 'GET', 
          success: function(result) { 


           var id = result.id; 
           var title = result.title; 
           var body = result.body; 
           var level = result.level 
           **console.log(level);** 

           //SHOW TOPIC and FAVTOPIC AS POPUP WHEN CLICKED 

           //Add proper favorite icon. 
           var favlink = '/topics/' + id + '/favorite';  
           **console.log(heartClass);** 
           var topicInfo = {title: title, body: body, heartClass: heartClass}; 
           var template = compiled(topicInfo); 



           $('.topic-wrapper').append(template); 

           //CLOSE TOPIC WHEN CLICKING THE GREY SURROUNDING BOX - topicClose 
           $('.topicClose').click(function(e) { 
            $('.topicClose').css("display", "none"); 
            $('.show_topic').css("display", "none"); 
           }) 

           //FAVORITE TOPIC 
           //ADD TO FAV TOPICS LIST 

           $(".unfavorited_heart_icon, .favorited_heart_icon").click(function(e) { 
            e.preventDefault(); 
            //onclick - change colors of heart 

            if ($(this).hasClass("favorited_heart_icon")) { 
             $(this).removeClass("favorited_heart_icon"); 
             $(this).addClass("unfavorited_heart_icon"); 
             urlEnd = '/unfavorite'; 
            } 
            else if ($(this). hasClass("unfavorited_heart_icon")) { 
             $(this).removeClass("unfavorited_heart_icon"); 
             $(this).addClass("favorited_heart_icon"); 
             urlEnd = '/favorite'; 
            } 
            // console.log('/topics/favorite/' + id); 
            $.ajax({ 
             url: '/topics/' + id + urlEnd, 
             type: 'POST', 
             success: function(result) { 
              location.reload(); 
             } 
            }) 

           }); 



          }, 
          error: function(err) { 
           console.log(err); 
          } 


         }) 
        }); 


      }; 

     }, 
     error: function(err) { 

     } 
    }); 

EDIT **

私も試してみた:私はresultsがおよそ20項目であることを推測している

$.ajax({ 
       url: '/topics', 
       dataType: 'json', 
       type: 'GET', 
       success: function(result) { 
        for(var i = 0; i < result.length; i++) { 
         var title = result[i].title; 
         var level = result[i].level; 
         var id = result[i].id; 
         var favlink = '/topics/' + id + '/favorite';  
         var link = '/topics/' + id; 
         var topicInfo = {title: title, link: link}; 
         var template = compiledTopics(topicInfo); 
         $('.topic-wrapper').append(template).click(function(e) { 
          e.preventDefault(); 
          console.log($(this)) 
         }); 
       }; 
      }, 
+1

あなたはあなたのループ内で合計20人のイベントリスナーを結合している:

私は、概念的にも似たような何かをしようとするだろう。 20件すべてがクリックで呼び出されます。 – Xufox

+0

@ user2267175 ajax呼び出しの前に1つ追加しましたが、1回だけ実行されました。電話の中で何か起きているようです。 – gwalshington

+2

「結果」は約20項目だと推測しています。あなたのforループ内で 'click'イベントハンドラを作成しているときは、' .listing-topics、.favorite-topic-title'クラスにバインドします。要素をクリックすると、クリックイベントが発生します(結果の配列に20項目あるので20回)。私はこれが起こっていると思うが、確認するためにそれを見る必要がある。あなたはJSFiddleを持っていますか? – mwilson

答えて

0

。 forループ内でclickイベントハンドラを作成するときは、クラス.listing-topics, .favorite-topic-titleにバインドします。要素をクリックすると、クリックイベントが発生します(結果の配列に20項目あるので20回)。私はこれが起こっていると思うが、確認するためにそれを見る必要がある。あなたはJSFiddleを持っていますか?

これを修正するには、イベントハンドラをバインドする方法を変更します。一度にすべてではなく個別にイベントを発生させるには、クラスまたは要素の特定のインスタンスにスコープを設定する必要があります。

サンプルシナリオ

var results = ["1", "2", "3"]; 


//How you're currently doing it 
for (var i = 0; i < results.length; i++) { 
    $('#container').append($('<div />', {text: results[i], class:'test-class'})); 
    $('.test-class').click(function() { 
    console.log($(this).text()); 
    }); 
} 

//Solution 
for (var i = 0; i < results.length; i++) { 
    $('#container').append($('<div />', {text: results[i], class:'test-class'}).click(function() { 
    console.log($(this).text()); 
    })); 
} 

私はより良い何が起こっているか説明するために(あなたと合わせる)このシナリオの簡単な再現を作成しました。基本的には、すべてのイベントを1つのクラス内でバインドして、それを作成するときに要素にバインドしてください。

JSFIDDLE:https://jsfiddle.net/ncrxekmq/

更新されたコード

if(window.location.pathname === "/topics") { 
    $('.actions').click(function(e) { 
     console.log("submit"); 
    }) 

    $.ajax({ 
      url: '/topics', 
      dataType: 'json', 
      type: 'GET', 
      success: function(result) { 
       console.log(result); 
       for(var i = 0; i < result.length; i++) { 
        var title = result[i].title; 
        var level = result[i].level; 
        var id = result[i].id; 
        var favlink = '/topics/' + id + '/favorite';  
        var link = '/topics/' + id; 
        var topicInfo = {title: title, link: link}; 
        var template = compiledTopics(topicInfo); 
        $('.topic-wrapper').append(template); 


       //use $.each(index, item) to loop through all of your elements and bind the click event individually instead of in one go. 
       $('.listing-topics, .favorite-topic-title').each(function (index, item) { 
        $(item).click(function(e){ 
         e.preventDefault(); 
         if($(this).hasClass("favorite-topic-title")) { 
          var heartClass = "favorited_heart_icon" 

         } 
         else if($(this).hasClass("listing-topics")) { 
          var heartClass = "unfavorited_heart_icon"; 
          $('html, body').animate({ scrollTop: 0 }, 'fast'); 

         } 
         **console.log(this);** 
         $.ajax({ 
          url: this, 
          dataType: "json", 
          type: 'GET', 
          success: function(result) { 


           var id = result.id; 
           var title = result.title; 
           var body = result.body; 
           var level = result.level 
           **console.log(level);** 

           //SHOW TOPIC and FAVTOPIC AS POPUP WHEN CLICKED 

           //Add proper favorite icon. 
           var favlink = '/topics/' + id + '/favorite';  
           **console.log(heartClass);** 
           var topicInfo = {title: title, body: body, heartClass: heartClass}; 
           var template = compiled(topicInfo); 



           $('.topic-wrapper').append(template); 

           //CLOSE TOPIC WHEN CLICKING THE GREY SURROUNDING BOX - topicClose 
           $('.topicClose').click(function(e) { 
            $('.topicClose').css("display", "none"); 
            $('.show_topic').css("display", "none"); 
           }) 

           //FAVORITE TOPIC 
           //ADD TO FAV TOPICS LIST 

           $(".unfavorited_heart_icon, .favorited_heart_icon").click(function(e) { 
            e.preventDefault(); 
            //onclick - change colors of heart 

            if ($(this).hasClass("favorited_heart_icon")) { 
             $(this).removeClass("favorited_heart_icon"); 
             $(this).addClass("unfavorited_heart_icon"); 
             urlEnd = '/unfavorite'; 
            } 
            else if ($(this). hasClass("unfavorited_heart_icon")) { 
             $(this).removeClass("unfavorited_heart_icon"); 
             $(this).addClass("favorited_heart_icon"); 
             urlEnd = '/favorite'; 
            } 
            // console.log('/topics/favorite/' + id); 
            $.ajax({ 
             url: '/topics/' + id + urlEnd, 
             type: 'POST', 
             success: function(result) { 
              location.reload(); 
             } 
            }) 

           }); 



          }, 
          error: function(err) { 
           console.log(err); 
          } 


         }) 
        }); 
       }); 

      }; 

     }, 
     error: function(err) { 

     } 
    }); 
+0

私はこの論理に同意しますが、 'this'を経由せずにクリックしている特定のインスタンスを一意に特定でき、トピックインスタンスの総数に関連付けられないようにするにはどうすればいいですか?ありがとう! – gwalshington

+0

JSFiddleでサンプルシナリオを作成して説明します。 – mwilson

+0

JSFiddleが追加されました。これが役に立ったら教えてください! – mwilson

1

私はあなたが複数のイベントリスナの割り当てを持っている問題の多くは外にそれらのリスナーを取ることによって解決することができると思います代理ストラテジを使用してループを定義します。

function getTopicJSON_Success(result){ 
    console.log(result); 

    for(var i = 0; i < result.length; i++) { 
     var title = result[i].title; 
     var level = result[i].level; 
     var id = result[i].id; 
     var favlink = '/topics/' + id + '/favorite';  
     var link = '/topics/' + id; 
     var topicInfo = { title: title, link: link }; 
     var template = compiledTopics(topicInfo); 
     $('.topic-wrapper').append(template); 
    } 
} 

function getJSON_Error(err){ 
    console.log(err); 
} 

if(window.location.pathname === "/topics") { 

    $('.actions').click(function(e) { 
     console.log("submit"); 
    }); 

    $('.topic-wrapper').on("click", '.listing-topics, .favorite-topic-title', function(e){ 
     e.preventDefault(); 

     // ========================= 
     // Note at this point "this" is the element that was clicked. 
     // in the ajax requrest below we will want to use $this.attr("href"). 
     // ========================= 
     console.log(this); 
     // ========================= 

     var $this = $(this); 
     var heartClass; 

     if($this.hasClass("favorite-topic-title")) { 
      heartClass = "favorited_heart_icon" 
     } else if($this.hasClass("listing-topics")) { 
      heartClass = "unfavorited_heart_icon"; 
      $("body").animate({ scrollTop: 0 }, 'fast'); 
     } 

     // ========================= 
     // Note: could be "null". 
     // Did you want one or the other specifically and not the posibility of null? 
     // ========================= 
     console.log(heartClass); 
     // ========================= 

     var getListJSON_Success = function(result){ 
      var id = result.id; 
      var title = result.title; 
      var body = result.body; 
      var level = result.level 

      console.log(level); 

      //SHOW TOPIC and FAVTOPIC AS POPUP WHEN CLICKED 

      //Add proper favorite icon. 
      var favlink = '/topics/' + id + '/favorite';  
      var topicInfo = {title: title, body: body, heartClass: heartClass}; 
      var template = compiled(topicInfo); 

      $('.topic-wrapper').append(template); 

      //CLOSE TOPIC WHEN CLICKING THE GREY SURROUNDING BOX - topicClose 
      $('.topicClose').click(function(e) { 
       $('.topicClose').css("display", "none"); 
       $('.show_topic').css("display", "none"); 
      }); 

      //FAVORITE TOPIC 
      //ADD TO FAV TOPICS LIST 
     }; 

     $.ajax({ 
      url: $this.attr("href"), 
      dataType: "json", 
      type: 'GET', 
      success: getListJSON_Success, 
      error: getJSON_Error 
     }) 
    }); 

    $('.topic-wrapper').on("click", ".unfavorited_heart_icon, .favorited_heart_icon", function(e) { 
     e.preventDefault(); 

     var $this = $(this); 
     var urlEnd; 

     if ($this.hasClass("favorited_heart_icon")) { 
      $this.removeClass("favorited_heart_icon"); 
      $this.addClass("unfavorited_heart_icon"); 
      urlEnd = '/unfavorite'; 
     } else if ($this. hasClass("unfavorited_heart_icon")) { 
      $this.removeClass("unfavorited_heart_icon"); 
      $this.addClass("favorited_heart_icon"); 
      urlEnd = '/favorite'; 
     } 

     $.ajax({ 
      url: '/topics/' + $this.attr("id") + urlEnd, 
      type: 'POST', 
      success: function(result) { location.reload(); }, 
      error: getJSON_Error 
     }); 

    }); 

    $.ajax({ 
     url: '/topics', 
     dataType: 'json', 
     type: 'GET', 
     success: getTopicJSON_Success, 
     error: getJSON_Error 
    }); 
} 
関連する問題