2011-12-07 70 views
10

这是一个来自JS新手的两部分问题。BackboneJS with XML ajax

所以,我试图创建一个使用requireJS的主干应用程序,方法如下:Thomas Davis's tutorial

  1. 我该如何去创建一个Ajax调用中的Backbone集合到一个提供XML数据的服务器? collections.fetch()似乎期待JSON后端。

  2. 在尝试一些事情时,我结束了以下代码,其中在从Ajax success-callback中填充集合“bookStore”时页面不刷新。

    这是我到目前为止得到了多少。

    var bookListView = Backbone.View.extend({ 
        el: $("#books"), 
        initialize: function() { 
         thisView = this; 
         $.ajax({ 
          type: "GET", 
          url: "books.xml", 
          dataType: "xml", 
          success: function (data) { 
           console.log(data); 
           $(data).find('book').each(function (index) { 
            var bookTitle = $(this).find('name').text(); 
            bookStore.add({ title: bookTitle }); 
    
            console.log(seid); 
           }); 
           thisView.collection = bookStore; 
           thisView.collection.bind('add', thisView.tryBind); 
    
          } 
         }).done(function (msg) { 
          alert("Data retrieved: " + msg); 
         }); 
    
         this.collection = bookStore; 
         this.collection.bind("add", this.exampleBind); 
         this.collection.bind("refresh", function() { thisView.render(); }); 
         /* 
         // This one works! 
         bookStore.add({ name: "book1" }); 
         bookStore.add({ name: "book2" }); 
         bookStore.add({ name: "book3" }); 
         */ 
        }, 
        tryBind: function (model) { 
         console.log(model); 
        }, 
        render: function() { 
         var data = { 
          books: this.collection.models, 
         }; 
         var compiledTemplate = _.template(bookListTemplate, data); 
         $("#books").html(compiledTemplate); 
        } 
    }); 
    

在这里,成功回调中的“初始化”功能似乎是正确处理数据并添加到集合中。但是,页面不刷新。

当我单步执行Firebug控制台时,页面会刷新。我该如何解决这个问题?

回答

23
  1. 您可以覆盖默认的parse函数来提供XML支持。应该转化成JSON数据http://backbonejs.org/#Collection-parse

  2. 绑定渲染返回到reset事件,而不是refresh骨干< 1.0或到sync事件骨干> = 1.0

它看起来是这样的

var Book = Backbone.Model.extend(); 

var Books = Backbone.Collection.extend({ 
    model: Book, 
    url: "books.xml", 

    parse: function (data) { 
     var $xml = $(data); 

     return $xml.find('book').map(function() { 
      var bookTitle = $(this).find('name').text(); 
      return {title: bookTitle}; 
     }).get(); 
    }, 

    fetch: function (options) { 
     options = options || {}; 
     options.dataType = "xml"; 
     return Backbone.Collection.prototype.fetch.call(this, options); 
    } 
}); 

var bookListView = Backbone.View.extend({ 
    initialize: function() { 
     this.listenTo(this.collection, "sync", this.render); 
    }, 

    render: function() { 
     console.log(this.collection.toJSON()); 
    } 
}); 

var bks = new Books(); 
new bookListView({collection: bks}); 
bks.fetch(); 

并演示http://jsfiddle.net/ULK7q/73/

+0

nikoshr,非常感谢。我试过了。而且,它的工作原理。 – Karthik

+0

还有一个问题。我应该从路由器代码执行获取吗?如果我这样做,每次访问时,包括浏览器后退按钮,代码最终都会从服务器中重新获取集合。 – Karthik

+0

您可能可以在您的init代码中实例化列表,并将其传递给您的路由器,而不是将获取与路由绑定。请注意,推荐的方法是在页面中使用序列化的JSON引导您的应用程序。 http://documentcloud.github.com/backbone/#FAQ-bootstrap – nikoshr