骨干路由器无法通信并发送url param进行查看

时间:2016-02-20 00:31:45

标签: javascript node.js backbone.js

我知道如何使用侦听器从我的视图中过滤集合,但我无法使用骨干路由器和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 /视图/ 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',
});

2 个答案:

答案 0 :(得分: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));
    }
});

未测试!

答案 1 :(得分: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 /#/ filter /:test now outputs

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

这就是我想要实现的目标。

PS:我为模糊的问题道歉,没有做足够的研究(因为我能够解决自己的问题)。我一定不要再犯这个错误了。