模型没有触发解析功能

时间:2014-11-29 00:44:24

标签: javascript jquery backbone.js marionette backbone-views

我遇到的问题是我的骨干模型没有正确解析。这是listing.js:

SpendYourSavings.Models.Listing = Backbone.Model.extend({
    urlRoot: "api/listings/",
    images: function() {
        this._images = this._images || new SpendYourSavings.Collections.Images([], { listing: this });
        return this._images;
    },
    reviews: function() {
        this._reviews = this._reviews || new SpendYourSavings.Collections.Reviews([], { listing: this });
        return this._reviews;
    },
    shop: function() {
        this._shop = this._shop || new SpendYourSavings.Models.Shop([], { listing: this });
        return this._shop;
    },


    parse: function(data) {
        if(data.images) {
            this.images().set(data.images, { parse: true });
            delete data.images;
        }
        if(data.reviews) {
            this.reviews().set(data.reviews, { parse: true });
            delete data.reviews;
        }
        if(data.shop) {
            this.shop().set(data.shop, { parse: true });
            delete data.shop;
        }
        return data;
    }
});

图片和评论有效,但商店并不起作用。它正确设置了商店的属性,但它没有正确设置图像。

这是shop.js:

SpendYourSavings.Models.Shop = Backbone.Model.extend({
    urlRoot: "/api/shops",

    reviews: function() {
        this._reviews = this._reviews || new SpendYourSavings.Collections.Reviews([], {});
        return this._reviews;
    },

    listings: function() {
        this._listings = this._listings || new SpendYourSavings.Collections.Listings([], {});
        return this._listings;
    },

    user: function() {
        this._user = this._user || new SpendYourSavings.Models.User([], {});
        return this._user;
    },

    image: function() {
        this._image = this._image || new SpendYourSavings.Models.Image([], {});
        return this._image
    },

    parse: function(data) {
        console.log("shop parse data: " + data);
        debugger
        if(data.listings) {
            this.listings().set(data.listings, { parse: true });
            delete data.listings;
        }
        if(data.reviews) {
            this.reviews().set(data.reviews, { parse: true });
            delete data.reviews;
        }
        if(data.user) {
            this.user().set(data.user, { parse: true });
            delete data.user;
        }
        if(data.image) {
            debugger
            this.image().set(data.image, { parse: true });
            delete data.image;
        }
        return data
    }

});

shop.js中的解析函数甚至从我在listing.js解析函数中收到商店时都没有! shop.image()没有正确设置图片模型,所以我必须调用像shop.get('image').url这样的东西来获取网址。

2 个答案:

答案 0 :(得分:1)

您的问题是parse: true set只适用于收藏。

这些行

this.images().set(data.images, { parse: true });
this.reviews().set(data.reviews, { parse: true });

工作,因为你说“从这个JSON添加全新的模型”。

这一行

this.image().set(data.image, { parse: true });
然而,试图说,解析这些参数并设置值,但这对模型来说很奇怪。它应该只是解析传入的属性吗?它应该合并模型已有的属性吗?如果模型中已有的东西与正在解析的东西之间存在依赖关系怎么办?

相反,您可以尝试重构顶级解析,例如

SpendYourSavings.Models.Listing = Backbone.Model.extend({
    urlRoot: "api/listings/",
    images: function() {
        return this.get('images');
    },
    reviews: function() {
        return this.get('reviews');
    },
    shop: function() {
        return this.get('shop');
    },

    parse: function(data) {
        if (data.images){
            data.images = new SpendYourSavings.Collections.Images(data.images, { listing: this, parse: true});
        }
        if (data.reviews){
            data.reviews = new SpendYourSavings.Collections.Reviews(data.reviews, { listing: this, parse: true});
        }
        if (data.shop){
            data.shop = new SpendYourSavings.Models.Shop(data.shop, { listing: this, parse: true});
        }
        return data;
    }
});

答案 1 :(得分:1)

据推测,您在商店中记忆图像模型的原因是为了维护听众并保留该模型的单个实例。

Collection#set采用parse选项,告诉它在集合上设置的所有模型上调用解析。 Model#set是使用从parse返回的属性在调用解析后立即调用的方法。

在这种情况下,我们希望使用已解析的属性在关联的#set模型上调用shop。首先,请致电parse。看起来应该是这样的:

SpendYourSavings.Models.Listing = Backbone.Model.extend({
    urlRoot: "api/listings",

    images: function() {
        this._images = this._images || new SpendYourSavings.Collections.Images([], { listing: this });
        return this._images;
    },

    reviews: function() {
        this._reviews = this._reviews || new SpendYourSavings.Collections.Reviews([], { listing: this });
        return this._reviews;
    },

    shop: function() {
        // Notice the first argument is an object when initializing models.
        this._shop = this._shop || new SpendYourSavings.Models.Shop({}, { listing: this });
        return this._shop;
    },

    parse: function(data) {
        if(data.images) {
            this.images().set(data.images, { parse: true });
            delete data.images;
        }
        if(data.reviews) {
            this.reviews().set(data.reviews, { parse: true });
            delete data.reviews;
        }
        if(data.shop) {
            var shopParams = this.shop().parse(data.shop);
            this.shop().set(shopParams);
            delete data.shop;
        }
        return data;
        }
    }
});