2013-12-19 2 views
3

Backbone.js (Underscore 템플릿 사용), Express 및 Node.js로 앱을 제작하고 있습니다.백본 템플릿을 렌더링 한 후 jQuery 코드를 호출하는 방법은 무엇입니까?

이 간단한 문제를 설명하기 위해 예제를 만들었습니다 (아래 코드 참조). 앱은 서버에서 검색된 "제목"목록으로 구성됩니다.

밑줄 서식 파일을 사용하여 HTML을 렌더링합니다. HTML이 렌더링 된 후, 예를 들어 각 "제목"의 position() 콘솔에서 인쇄하는 것과 같이 일부 jQuery 코드를 실행하고 싶습니다. 문제는 템플릿에 DOM 요소를 삽입하기 전에 jQuery 코드가 호출되어 jQuery가 요소를 찾을 수 없다는 것입니다.

무엇이 누락 되었습니까? html을 DOM에 삽입 한 후 이벤트를 가져 오는 방법이 있습니까? 여기에 코드

:

<div class="container"> 
     <div id="tracks"> 

     </div> 
    </div> 

    <!-- Template --> 
    <script id="trackTemplate" type="text/template"> 

     <ul id="<%= id2 %>" style="height:150px"> 
      <li><%= title %></li> 
     </ul>    

     <% 
     // So it looks like this code gets code before the template's HTML is in the DOM. 
      console.log($("#"+id2).position()); 
     %> 
    </script> 

    <script src="js/lib/jquery-1.10.2.min.js"></script> 
    <script src="js/lib/underscore-min.js"></script> 
    <script src="js/lib/backbone-min.js"></script> 
    <script> 
    var app = app || {}; 

    // Model 
    app.Track = Backbone.Model.extend({ 
     defaults: { 
      id2: '', 
      title: 'Track', 
     }, 
    }); 

    // Collection 
    app.Library = Backbone.Collection.extend({ 
     model: app.Track, 
     url: '/api/tracks' 
    }); 

    // Track view 
    app.TrackView = Backbone.View.extend({ 
     tagName: 'div', 
     className: 'trackContainer', 
     template: _.template($('#trackTemplate').html()), 
     initialize:function(){ 
      this.model.on('change', this.render, this); 
     }, 
     render: function() { 
      this.$el.html(this.template(this.model.toJSON())); 

      return this; 
     }, 

    }); 

    // Collection View 
    var numberOfTracks = 0; 
    app.LibraryView = Backbone.View.extend({ 
     el: '#tracks', 

     initialize: function(initialTracks) { 
      this.collection = new app.Library(initialTracks); 
      this.collection.fetch(); 
      this.listenTo(this.collection, 'add', this.renderTrack); 
     }, 

     // render library by rendering each track in its collection 
     render: function() { 
      this.collection.each(function(item) { 
       this.renderTrack(item); 
       numberOfTracks++; 
      }, this); 
     }, 

     // render a track by creating a trackView and appending the 
     // element it renders to the library's element 
     renderTrack: function(item) { 
      var trackView = new app.TrackView({ 
       model: item 
      }); 
      this.$el.append(trackView.render().el); 
     }, 
    }); 

    // Initialise app 
    var libraryView = new app.LibraryView(); 
    </script> 

주셔서 감사합니다 console.log 통화

답변

0
  • 오른쪽 장소는 바로 append 후, 당신의 render 방법의 끝에 또는 renderTrack에있을 것입니다.

  • 백본을 사용하면 자신의 이벤트를 쉽게 만들고 Backbone.Events을 통해 가입 할 수 있습니다. 이전 단락에서 언급 한 장소 중 하나에서 자신의 이벤트를 시작할 수 있습니다.

  • Mutation events이라고하는 DOM의 변경 사항을 추적하기 위해 사용되지 않는 이벤트 패밀리가 있지만 더 이상 사용되지 않으며 브라우저 지원은 신뢰할 수 없습니다. 대체는 DOM4 spec에 정의 된 MutationObserver이며, 브라우저 지원은 아직 없습니다 (IE는 11에서만 지원됩니다). 그러나 테스트를 위해 유용 할 수 있습니다.

  • 또 다른 방법은 코드를 setTimeout에 넣는 것입니다.이 방법을 사용하면 console.log이 실행될 때 DOM 노드가 반드시 삽입됩니다.

+0

'render' 메소드의 끝에'console.log'를 넣으려고했으나 문제를 해결하지 못했습니다.내가 말한대로 이벤트를 시작할 수 있지만 문제는 템플릿 렌더링 (이벤트를 발생시킬 수 있음)과 DOM의 HTML 요소 삽입 사이에 약간의 시간이 있다는 것입니다. HTML이 DOM에있을 때 필요한 이벤트와 이벤트입니다. 귀하의 답변에 감사드립니다. – andreugrimalt

+0

@andreugrimalt 정확히 어디에 넣고 있으며 어떤 코드를 넣고 있습니까? 그 결과는 무엇입니까? 엘리먼트는'append' /'html'이 호출 된 직후에 DOM에 삽입되어야합니다. – kapa

+0

결과는 다음과 같습니다 :'Uncaught TypeError : Object [object Object]에는 'postion'메서드가 없습니다. 이것은 요소가 존재하지 않는다는 것을 의미합니다 ... 사실'$ ("#"+ id2) .length'는 0을 반환합니다. 나는'append'가 호출 된 직후에 DOM에 요소가 삽입되어야한다는 것에 동의합니다. 불행히도 그것은 사실이 아닙니다 ... – andreugrimalt

1

여기에 약간의 근거를 설명하기 위해 무언가가 DOM에 삽입되면 발생하는 이벤트가 없습니다. 나는 실제로 당신의 템플릿 안에 코드를 넣음으로써 그것을 해결하려고 노력하는 것을 옹호하지 않을 것이다. 보기가 렌더링되는 방식을 살펴보십시오.

당신은 당신이이 같은 일을 볼 수있는 기존의 장소 홀더에 몇 가지 코드를 던져하려면 :

http://ianstormtaylor.com/rendering-views-in-backbonejs-isnt-always-simple/

:

[view here].setElement(this.$([selector here])).render(); 

에서 이것의 훌륭한 설명이있다을

헤비급 하위 뷰 관리가 필요하지 않은 경우 하위보기를 정렬하는 깔끔한 방법입니다. 그 후 jquery를 사용하여 일반적으로 뷰 내에서이 작업을 수행 할 수 있어야합니다. $ el 및 this. $. 요소를 제공하면보기 내에서 올바르게 범위가 지정됩니다.

관련 문제