开发者

Backbone.js Issue When Saving Model

I am having an issue with backbone.js and the model.save() method. I have included a complete example below although without the three libraries needed.

I have a tag model, a tag collection model, and a model to represent some selected items in my UI, called search criteria.

I am getting a url error when attempting to save the model after I have manipulated the search criteria's collection of tags. This example illustrates the issue.

It appears that on the final call to save in this example, backbone cannot resolve the url which is defined in the tag collection model.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test</title>
    <script src="Scripts/Libraries/jquery-1.6.1.js" type="text/javascript"></script>
    <script src="Scripts/Libraries/underscore.js" type="text/javascript"></script>
    <script src="Scripts/Libraries/backbone.js" type="text/javascript"></script>

    <script language="javascript" type="text/javascript">

        $(function () {

            // Simple model for a tag. Tags have an id and a title.
            var TagModel = Backbone.Model.extend({});

            // Collection for tags.
            var TagCollection = Backbone.Collection.extend({
                model: TagModel,
                url: "tags"
            });

            // Sample model to hold a set of "selected" search criteria.
            // Includes search text and a collection of "se开发者_C百科lected" tags.
            var SearchCriteriaModel = Backbone.Model.extend({
                defaults: {
                    "searchText": "",
                    "tags": new TagCollection()
                }
            });

            // Create master tags collection.
            window.tags = new TagCollection();
            window.tags.refresh([
                { id: 1, title: "Tag A" },
                { id: 2, title: "Tag B" },
                { id: 3, title: "Tag C" }
            ]);

            // Create search criteria.
            window.searchCriteria = new SearchCriteriaModel();

            // Should be 3 tags.
            console.log("Should be 3 tags in master tags list.");
            console.log("Count = " + window.tags.size());

            // Should be 0 tags in criteria collection.
            console.log("Should be 0 selected tags.");
            console.log("Count = " + window.searchCriteria.get("tags").size());

            // Update tag title for tag 1.
            var tag = window.tags.get(1);
            tag.set({ "title": "Tag AA" });

            // Save tag.
            console.log("Try to save tag. Should attempt PUT to /tags/1. WORKS.")
            tag.save();

            // Add tag to search criteria.
            window.searchCriteria.get("tags").add(tag);

            // Should be 1 tag in criteria collection now.
            // I am not moving the tag, but rather wanting to simply add a reference to the tag to the
            // criteria collection.
            console.log("Should be 1 selected tags.");
            console.log("Count = " + window.searchCriteria.get("tags").size());

            // Should STILL be 3 tags in the master list.
            console.log("Should be 3 tags in master tags list.");
            console.log("Count = " + window.tags.size());

            // Update tag title for tag 1 again.
            var tag = window.tags.get(1);
            tag.set({ "title": "Tag AAA" });

            // Save tag.
            console.log("Try to save tag. Should attempt PUT to /tags/1. WORKS.")
            tag.save();

            // Remove tag from criteria. Simulates someone "deselecting" a tag from the search.
            window.searchCriteria.get("tags").remove(tag);

            // Should be 0 tags selected.
            console.log("Should be 0 selected tags.");
            console.log("Count = " + window.searchCriteria.get("tags").size());

            // Save tag. FAILS.
            console.log("Try to save tag. Should attempt PUT to /tags/1, but does not. Instead throws error 'A url property or function must be specified'.");
            tag.save();

        });

    </script>

</head>
<body>
    <h1>Test</h1>
    <p>Backbone test page.</p>
</body>
</html>

Any thoughts? Thanks!

UPDATED

I updated the code to help illustrate that I am not moving the tag between collections, but rather adding a reference to the tag to a second collection. Then, when I remove the tag from the second collection (not the first), Backbone cannot resolve the first collection, and then cannot get the url for saving.

I am confused as to why removing the tag from one collection would have an impact on the reference to that tag in a separate collection.

I am coming from a C# background. Maybe objects and collections work differently here.


You've got two collections of tags running (one on window and one defined in your SearchCriteriaModel) and you appear to be moving a tag between the two collections

When you execute this line of code:

window.searchCriteria.get("tags").remove(tag);

The link between that tag and a collection is lost.. the URL is determined from the collection.

Note that if you remove the line above, your tag saves as it gets it URL from your window.tags collection.

Ps.. good question, well asked, nicely formatted code sample demonstrating the problem.


Don't know if this solves your problem, but you should first change your url to "/tags" instead of just "tags"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜