动态设置主干集合url返回没有属性的模型

时间:2014-09-15 00:23:34

标签: backbone.js typescript backbone-collections

我有一个与Rails Web服务绑定的骨干移动应用程序。其他对象的所有模型都被正确加载和显示,但是这个特定的模型没有。我遇到的问题是Item被创建,但不加载属性。我已经确认了rails api的正确json输出。此集合与此应用程序的所有其他集合之间的区别在于此集合具有必须在URL中使用的parentID才能加载正确的项目(category_id)。

现在......有趣的是,如果我将{category_id: options.attributes[0].category_id}参数移除到ItemCollectionView的构造函数调用并将category_id直接硬编码到网址中,它就可以了! (但是我需要根据父视图的类别动态分配它。

以下是我的课程:

export class ItemCollectionView extends Backbone.View {
    public template: string;
    public collection: itemsImport.Items;

    constructor(options?: Backbone.ViewOptions){
        this.collection = new itemsImport.Items({category_id: options.attributes[0].category_id});
        super(options);
    }
    ...
    public addOne(item: itemImport.Item): void{
        var view: itemItemImport.ItemItemView = new itemItemImport.ItemItemView({el: this.el, model: item});
        //Breakpoint right here shows that item.attributes.id = undefined
        view.render();
    }
}

export class Items extends Backbone.Collection {
    public url: string;

    constructor(attributes?: any, options?: any){
        this.url = 'http://localhost:3000/categories/' + attributes.category_id + '/items';
        this.model = itemImport.Item;
        super(attributes, options);
    }
}

在我的调试中,我可以确认:

options.attributes[0].category_id == 1;

this.url == 'http://localhost:3000/categories/1/items';

该网址的回复是:

[{"id":1,"category_id":1,"title":"Item 1","description":null,"active":true,"comment":null,"extra":null,"deleted":"0","url":"http://localhost:3000/categories/1/items/1.json"},{"id":2,"category_id":1,"title":"Item 2","description":null,"active":true,"comment":null,"extra":null,"deleted":"0","url":"http://localhost:3000/categories/1/items/2.json"}]
你可以看到

是一个正确的json响应。

所以我的问题是:我做错了什么? ||将变量动态传递到集合中以在运行时设置正确的URL的正确方法是什么?

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

url定义为函数,如第二种情况here

var Notes = Backbone.Collection.extend({
    url: function() {
        return this.document.url() + '/notes';
    }
});

如果您确实加载了正确的网址,请检查网络标签。

答案 1 :(得分:0)

如果使用javascript,选择的其他答案将有效,但如果使用TypeScript,编译器会抱怨url必须是属性,而不是方法。我找到的解决方案(也适用于javascript)是在集合的url方法上设置fetch()参数,如下所示

export class ItemCollectionView extends Backbone.View {
    public template: string;
    public collection: itemsImport.Items;

    constructor(options?: Backbone.ViewOptions){
        this.collection = new itemsImport.Items({category_id: options.attributes[0].category_id});
        super(options);
    }

    public initialize(options?:any): void {
        this.listenTo(this.collection, 'add', this.addOne);
        this.listenTo(this.collection, 'reset', this.addAll);
        this.collection.fetch({url: this.collection.seturl(options.attributes[0].category_id)});
    }

    ...

}

我希望这有助于未来用户在Backbone中寻找此功能

答案 2 :(得分:0)

可以在Typescript代码中为Backbone模型定义动态url属性。这比在url的所有调用中使用fetch()参数更好。

你可以使用ECMAScript 5 getter来做到这一点:

export class Items extends Backbone.Collection {
    get url(): string {
        return '/categories/' + this.get('category_id') + '/items';
    }

    constructor(attributes?: any, options?: any){
        this.model = itemImport.Item;
        super(attributes, options);
    }
}

或直接在prototype

上设置
export class Items extends Backbone.Collection {
    constructor(attributes?: any, options?: any){
        this.model = itemImport.Item;
        super(attributes, options);
    }
}
Items.prototype.url = function() { 
    return '/categories/' + this.get('category_id') + '/items'; 
};

第二个解决方案适用于所有浏览器。