2011-04-28 3 views
28

나는 백본 JS로 놀고 자 노력하고 있으며, 지금까지 모든 것이 합리적이고 원활하게 작동하고있는 것으로 보인다.백본 JS보기 이벤트가 실행되지 않습니까?

아래 코드를 사용하면 내 맞춤 이벤트가 실행되지 않는 것처럼 보입니다. 아래 코드의 내용은 그 이유가 무엇인지 알 수 있습니까? 보기에서 아무 것도 "초기화"해야합니까? 코드/구조체에 대한 다른 포인터도 멋지다. 아래는 내 전체 JS/HTML입니다.

JS

var Todo = Backbone.Model.extend({}); 

var TodoCollection = Backbone.Collection.extend({ 

    model: Todo, 
    url: '/Home/Todos' 

}); 

var AppView = Backbone.View.extend({ 

    // where it should listen, required? 
    el: $(".content"), 

    events: { 
     "keypress #new-todo": "enter" 
    }, 

    initialize: function() { 
     // _.bindAll(this, "render", "createOnEnter"); 
     // this.collection.bind("all", this.render); 
    }, 

    hi: function() { 
     alert('ohai'); 
    }, 

    render: function() { 
     var lis = ''; 
     $.each(this.collection.models, function() { 
      lis += '<li>' + this.get('Text') + '</li>'; 
     }); 
     $('#todo-list').append(lis); 
     return this.el; 
    }, 

    enter: function (e) { 
     alert('hi'); 
    } 

}); 


var TodoController = Backbone.Controller.extend({ 

    routes: { 
     "": "todos" 
    }, 

    initialize: function (options) { }, 

    todos: function() { 
     var todolist = new TodoCollection(); 
     todolist.fetch({ 
      success: function (data) { 
       var appview = new AppView({ collection: data }); 
       appview.render(); 
      } 
     }); 
    } 

}); 

$(function() { 
    window.app = new TodoController(); 
    Backbone.history.start(); 
}); 

HTML

<div id="todoapp"> 
    <div class="content"> 
     <input id="new-todo" placeholder="What needs to be done?" type="text" /> 
     <div id="todos"> 
      <ul id="todo-list"> 
      </ul> 
     </div> 
     <a href="#">say hey</a> 
    </div> 
</div> 

답변

37
el: $(".content") 

이를 시도해보십시오 DOM이 아직 생성되지 않기 때문에

var appview = new AppView({ el:$(".content"), collection: data }); 

당신은 거기에 jQuery를 호출 할 수 없습니다. 내보기 또는 초기화에서보기가로드 될 때 수행해야합니다.

+1

감사

는 그 정보를 전달하는 다른 매개 변수를 사용합니다. 그 시점에서 DOM이 생성되지 않는 이유는 아직도 조금 혼란 스럽습니다. 나는 컨트롤러를 바닥에서 찰칵 소리를 내고 문서 준비 호출 안에 감싼다. 그렇다면 내 컨트롤러 소식을 AppView, 그래서 그 시점에서 처음 '엘'전화 않을까요? – aherrick

+5

var AppView = Backbone.View.extend ({})는 브라우저가 읽을 때 평가됩니다. 문서 준비 호출에서 인스턴스화하지만 _el_는 함수가 아니므로 확장의 일부로 평가됩니다. – Julien

+3

Backbone.js Todo 예제가 AppView를 만들 때 매개 변수를 전달할 필요가없는 이유를 설명 할 수 있습니까? 그들은 todo.js의 맨 위에이 주석을 달았습니다. "// 일단 jQuery.ready'를 사용하여 DOM이 준비되면 응용 프로그램을로드하십시오 :"그러나 DOM 준비가되었는지 확인하기 위해 아무것도하지 않습니다. 감사. – Quentamia

16

또한 이벤트가 작동하려면 렌더링 기능의 콘텐츠를 this.el로 바인딩해야합니다. 이벤트는 모두 지정한 요소에 바인딩되므로 이벤트 생성 요소를 위임자 역할을하는 요소의 하위 요소로 바인딩해야합니다.

+3

나는이 코멘트를 두 번하고 싶지만, 할 수 없다. 정확히 10x 문제였다. –

+0

Backbone API에 대한 업데이트로 인해 변경되었습니다. 이제 el을 동적으로 설정하는 데 사용할 수있는 메소드가 있으며이를 사용하면 delegateEvents()가 해당 함수에 의해 자동으로 호출됩니다. –

+0

나는 백본을 아주 잘 모르지만, 엘 속성을 지정하지 않고 $ ('. content')를 수행하는 render 함수 안에서 이것을 해결할 것이라고 생각한다 .wrap (this.el); – BishopZ

1

승인 된 대답에는 단점이 있습니다. {el : $ (". content")}를 설정하면 매우 동적이어서는 안됩니다. DOM 내부에서 ".content"-Element를 다시 사용할 수 없습니다. 이 뷰에서 remove()를 호출하자마자 $ (".content")도 사라진다.

{ renderTarget: $("#content") }. 

및 렌더링의 시작 부분에서 DOM에 내 시야를 삽입 : 대답에 대한

initialize: function (options) { 
    options = options || {}; 
    this.renderTarget = options.renderTarget || this.renderTarget; 
}, 
render: function() { 
    if (this.renderTarget) { 
     $(this.renderTarget).html(this.el); 
    } 
    ... render stuff into $(this.el) ... 
    return this; 
} 
관련 문제