2016-11-01 8 views
-1

내 todos.js :컬렉션 길이가 0이지만 가져 오기가 성공한 이유는 무엇입니까?

var app = app || {}; 

(function() { 
    'use strict'; 
    var Todos = Backbone.Collection.extend({ 
     model: app.Todo, 
     url: '/api/todos' 
    }); 
    app.todos = new Todos(); 
})(); 

앱 view.js

var app = app || {}; 
(function($){ 
    'use strict'; 
    app.AppView = Backbone.View.extend({ 
     el: '.todoapp', 
     events : { 
      'keypress .new-todo': 'createOnEnter' 

     }, 

     initialize: function() { 
      this.$input = this.$('.new-todo'); 
      this.$list = $('.todo-list'); 
      app.todos.fetch({ 
       reset : true 
      }); 
      this.render(); 
     }, 


     render: function(){ 
      console.log(' len = ' + app.todos.length); 
      app.todos.each(function(todo){ 
       this.renderTodo(todo); 
      }, this); 
     }, 
... 

불러 온 데이터

[{ 
    "_id": "5801", 
    "title": "testtitle123", 
    "completed": false, 
    "__v": 0 
}, { 
    "_id": "58182", 
    "title": "testtitle126", 
    "completed": false, 
    "__v": 0 
}, { 
    "_id": "5813", 
    "title": "testtitle127", 
    "completed": false, 
    "__v": 0 
}] 

이 (http://myip:8000/api/todos에서) 데이터를 가져 오는 데 성공했다. 그러나 콘솔에서, 길이는 나는 다음과 같은 코드를 시도 0

UPDATE

항상이다. 콘솔에는 'OK'또는 'error'가 기록되지 않습니다.

var app = app || {}; 
    (function($){ 
     'use strict'; 
     app.AppView = Backbone.View.extend({ 
      el: '.todoapp', 
      events : { 
       'keypress .new-todo': 'createOnEnter' 

      }, 

      initialize: function() { 
       this.$input = this.$('.new-todo'); 
       this.$list = $('.todo-list'); 
       this.listenTo(app.todos, 'sync', this.render); 
       app.todos.fetch({ 
        reset : true, 
        context: this, 
        success: function(col, res, op) { 
         console.log('OK'); 
        }, 
        error: function(col, res, op){ 
         console.log('error'); 
        } 
       }); 
      }, 

      render: function(){ 
       console.log(' len = ' + app.todos.length); 
       app.todos.each(function(todo){ 
        this.renderTodo(todo); 
       }, this); 
      }, 

      renderTodo: function(todo) { 
       console.log('render :' + todo.title); 
       var todoView = new app.TodoView({ model : todo }); 
       this.$list.append(todoView.render().el); 
      }, 
     }); 

    })(jQuery); 
+0

수신 된 데이터 무엇입니까? –

+0

답변을 관련성이없고 혼란에 빠지게 만들기 때문에 질문에 대한 답변의 코드를 편집하지 마십시오. –

+0

그 시점에서 다른 코드가 작동해야하므로 조사해야합니다. 'render'가 다른 곳에서 호출 되었기 때문입니까? –

답변

1

fetch 비동기, 그래서 당신이 바로 후 렌더링 할 때, 컬렉션은 여전히 ​​비어 있습니다.

서버를 호출해야하는 함수는 정의에 따라 비동기입니다. 브라우저를 잠그지 않고는 동기식이 될 수 없습니다.

쉽게 해결하기 위해 백본에서 제공하는 콜백을 사용

{ 
    data: [ 
     {...}, 
     {...} 
    ] 
} 

당신은 parse 기능을 제공 할 필요가 다음 API로부터받은 데이터가 형식 인 경우, 또한

initialize: function() { 
    /** ...snip... */ 
    app.todos.fetch({ 
     reset: true, 
     context: this, 
     success: this.render 
    }); 
}, 

을 내 컬렉션에 넣기 :

var Todos = Backbone.Collection.extend({ 
    model: app.Todo, 
    url: '/api/todos', 
    parse: function(response) { 
     return response.data; 
    } 
}); 

var PostCollection = Backbone.Collection.extend({ 
 
    url: 'https://jsonplaceholder.typicode.com/posts', 
 
}); 
 

 

 
var collection = new PostCollection(); 
 
collection.fetch({ 
 
    reset: true, 
 
    context: this, 
 
    success: function() { 
 
    console.log("Success:", collection.length); 
 
    } 
 
}); 
 

 
Simplest demo of fetching and checking the `length`.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>

+0

시도했습니다. 작동하지 않습니다 ... – BAE

1

모든 인출은 비동기 있습니다 때문입니다. 따라서 렌더링이 실행되기 전에 렌더링이 실행 중입니다.

이 완료 인출 한 후에는 다시 쓰게 수 :

app.todos.fetch().done(function(){ 
    self.render(); 
}); 

는 또한 모델의 동기 이벤트를 수신 할 수 :

this.listenTo(app.todos, 'sync', this.render); 

http://backbonejs.org/#Sync

+0

여기에 jQuery promise API를 사용하지 않아도됩니다. –

+1

@ n00btron이 오류를 수정했습니다. js 파일을 가져 오는 순서가 잘못 되었기 때문입니다. 죄송합니다. – BAE

관련 문제