2016-02-20 61 views
0

我知道如何使用侦听器从我的视图中过滤集合,但我无法弄清楚如何使用骨干路由器和url来做到这一点。骨干路由器不能通信和发送url参数来查看

我无法从路由器访问我的视图或集合,因为它们尚未实例化。我的意思是我不能只是添加一个过滤器方法到我的集合,然后调用app.PurchaseList.filter。我可以创建一个包含已过滤项目的新集合,但是如何将此集合传递给我的视图?

一些问题使用PubSub解答,但​​我认为会有更直接的方法。或者,最好不要将url路由用于这样的任务,并直接从我的视图中触发事件(在这种情况下,整个过滤器代码可以保留在我的AppView视图中,使事情变得更容易)。

是的,我是初学者,这么多应该是显而易见的;)

JS /路由/ backboneRouter.js

var app = app || {}; 
app.Router = Backbone.Router.extend({ 
    routes: { 
     'filter/:filter': 'filter' 
    }, 

    filter: function(filter) { 
     //... 
    } 
}); 

的js/app.js

var app = app || {}; 

$(function() { 
    app.router = new app.Router(); 
    Backbone.history.start(); 
    app.appView = new app.AppView(); 
}); 

js/views/appView.js

var app = app || {}; 
app.AppView = Backbone.View.extend({ 
    el: '#app', 

    initialize: function() { 
     this.collection = new PurchaseList(); 
     this.collection.fetch({reset: true}); 
     this.render(); 
     this.listenTo(this.collection, 'add', this.renderPurchases); 
     this.listenTo(this.collection, 'reset', this.render); 
    }, 

    events: { 
     'click #add-purchase': 'addPurchase', 
    }, 

    filter: function(filter) { 
     console.log(filter); 
    }, 

    addPurchase: function(event) { 
     //... 
    }, 

    render: function() { 
     this.collection.each(function(item) { 
      this.renderPurchases(item); 
     }, this); 
    }, 

    renderPurchases: function(item) { 
     var purchaseView = new PurchaseView({ 
      model: item 
     }); 
     this.$('#list').append(purchaseView.render().el); 
    } 
}); 

JS /收藏/ purchases.js

var app = app || {}; 
app.PurchaseList = Backbone.Collection.extend({ 
    model: PurchaseItem, 
    url: 'api/purchase', 
}); 
+0

*“我无法从路由器访问我的视图或集合,因为它们尚未实例化”*,然后您正在从路由器执行'app.appView.filter('reset');'。这不是一个观点..?一般来说,我们根据来自路由器的路由初始化事物并传入url参数...如果您无法访问任何内容,可能应该考虑重新设计..? –

+0

对不起,这是一个剩余的函数调用,没有工作(过滤器未定义),从我实验时。 – Vey

回答

0

一般你让集合做过滤:

app.PurchaseList = Backbone.Collection.extend({ 
    model: PurchaseItem, 
    url: 'api/purchase', 
    by: (attribute, value) => { 
     let filter = {} 
     filter[attribute] = value 
     return new app.PurchaseList(this.where(filter)); 
    } 
}); 

未测试!

+0

谢谢,但这实际上不是给我麻烦的部分(编写一个工作过滤器)。我无法工作的是如何从我的路由器调用此功能。我的集合在我的视图中被实例化,这是(我猜)为什么我不能直接从路由器调用你的过滤器。我猜这有一些最佳实践。 – Vey

0

我现在意识到,我不应该在凌晨1点发布此消息,因为现在情况已经很清楚了。

我的第一个问题是集合仅在我的AppView中初始化。据我所知,没有其他函数可以访问该集合,因为它仅限于AppView的范围。

我通过将集合添加到我的应用程序的命名空间对象(var app = app || {})来将集合的初始化移动到全局范围,以便它可以在整个应用程序中作为app.purchaseList访问。

此外,直接调用视图或集合的功能是(请纠正我,如果我错了)不是一个好的做法。因此,路由器现在在我的集合上触发一个'过滤器'事件,我的视图正在侦听。通过触发器的第二个参数将过滤器值(/ filter /:filter)发送到集合(或我需要的任何地方)。

路由器

app.Router = Backbone.Router.extend({ 
    routes: { 
     'filter/:filter': 'filter' 
    }, 

    filter: function(value) { 
     console.log('router filter'); 
     app.purchaseList.trigger('filter', value); 
    } 
}); 

应用

var app = app || {}; 

$(function() { 
    app.appView = new app.AppView(); 
    app.router = new app.Router(); 
    Backbone.history.start(); 
}); 

收集

var app = app || {}; 
app.PurchaseList = Backbone.Collection.extend({ 
    model: PurchaseItem, 
    url: 'api/purchase', 
}); 
app.purchaseList = new app.PurchaseList(); 

查看

var app = app || {}; 
app.AppView = Backbone.View.extend({ 
    el: '#app', 

    initialize: function() { 
     //... 
     this.listenTo(app.purchaseList, 'filter', this.filterList); 
    }, 

    events: { 
     'click #add-purchase': 'addPurchase', 
    }, 

    filterList: function(value) { 
     console.log('appView filter'); 
     console.log(value); 
    }, 

    addPurchase: function(event) { 
     //... 
    }, 

    render: function() { 
     this.collection.each(function(item) { 
      this.renderPurchases(item); 
     }, this); 
    }, 

    renderPurchases: function(item) { 
     var purchaseView = new PurchaseView({ 
      model: item 
     }); 
     this.$('#list').append(purchaseView.render().el); 
    } 
}); 

去到localhost:8080 /#/过滤/:现在测试输出

Navigated to http://localhost:8080/ 
backboneRouter.js:8 router filter 
list.js:19 appView filter 
list.js:20 test 

这就是我想实现。 PS:我对这个模糊的问题表示歉意,没有做足够的研究(因为我能解决我自己的问题)。我一定不会再犯这个错误。