将我的主干模型,视图和集合分离到文件夹中

时间:2015-09-04 04:18:06

标签: javascript backbone.js

有人告诉我,我的项目应该在各自的文件夹中分离模型,视图和集合。这应该是一个简单的修复,但我不知道如何做到这一点,并让我的代码仍然可以运行。

这是我的JAVASCRIPT:

$(function() {

    var Food = Backbone.Model.extend({

        defaults: {
            title: 'no information found',
            brand: 'no information found',
            calories: 'no information found',
        }
    });

    var AllFoods = Backbone.Firebase.Collection.extend({
        model: Food,
        url: "https://blinding-torch-8751.firebaseio.com/allfoods"

    });
    var Breakfast = Backbone.Firebase.Collection.extend({
        model: Food,
        url: "https://blinding-torch-8751.firebaseio.com/breakfast"

    });
    var Lunch = Backbone.Firebase.Collection.extend({
        model: Food,
        url: "https://blinding-torch-8751.firebaseio.com/lunch"

    });
    var Dinner = Backbone.Firebase.Collection.extend({
        model: Food,
        url: "https://blinding-torch-8751.firebaseio.com/dinner"

    });
    var Snack = Backbone.Firebase.Collection.extend({
        model: Food,
        url: "https://blinding-torch-8751.firebaseio.com/snack"

    });



    var SearchList = Backbone.Collection.extend({

        initialize: function() {
            this.bind("reset", function(model, options) {
                console.log("Inside event");
                console.log(model);
            });
        },

        //** 1. Function "parse" is a Backbone function to parse the response properly
        parse: function(response) {
            //** return the array hits inside response, when returning the array
            //** we let Backone populate this collection
            return response.hits;
        }

    });


    var App = Backbone.View.extend({

        el: 'body',

        events: {
            "input #searchBox": "prepCollection",
            "click #listing li": "track",
            "click #add": "addClicked",
            "click #remove": "removeClicked"

        },

        initialize: function() {
            //set up variables used more globally
            this.foodid = "";
            this.model = new SearchList();
            this.foods = new AllFoods();
            this.breakfastlist = new Breakfast();
            this.lunchlist = new Lunch();
            this.dinnerlist = new Dinner();
            this.snacklist = new Snack();
            this.$total = $('#total span');
            this.$list = $('#listing');
            this.$instruct = $('#instruct');
            this.$tracked = $('#tracked');
            //code to respond to changes in the collections
            this.listenTo(this.foods, 'add', this.rendertracked);
            this.listenTo(this.foods, 'remove', this.rendertracked);
            this.listenTo(this.breakfastlist, 'add', this.renderbreakfast);
            this.listenTo(this.breakfastlist, 'remove', this.renderbreakfast);
            this.listenTo(this.lunchlist, 'add', this.renderlunch);
            this.listenTo(this.lunchlist, 'remove', this.renderlunch);
            this.listenTo(this.dinnerlist, 'add', this.renderdinner);
            this.listenTo(this.dinnerlist, 'remove', this.renderdinner);
            this.listenTo(this.snacklist, 'add', this.rendersnack);
            this.listenTo(this.snacklist, 'remove', this.rendersnack);
            //code to not fire off a request right away
            this.prepCollection = _.debounce(this.prepCollection, 1000);

        },

        addClicked: function(e) {
            var $target = $(e.currentTarget).parent();
            var $selected = $target.find('#mySelect').val();
            var location = $target.attr('data-id');
            //tracks the model selected in all of the collections
            var currentFood = this.foods.get(location);
            var currentBreakfast = this.breakfastlist.get(location);
            var currentLunch = this.lunchlist.get(location);
            var currentDinner = this.dinnerlist.get(location);
            var currentSnack = this.snacklist.get(location);
            //provides the html for the view
            var currenthtml = currentFood.get('html');

            switch ($selected) {

                //case statements make sure model is added to the proper meal collection
                //if elseif statements insure that no other collection except tracked has the same id-No duplicates
                case 'Breakfast':
                    this.breakfastlist.create(currentFood);

                    if (currentLunch) {
                        this.lunchlist.remove(currentLunch);
                    } else if (currentDinner) {
                        this.dinnerlist.remove(currentDinner);
                    } else if (currentSnack) {
                        this.snacklist.remove(currentSnack);
                    }
                    break;
                case 'Lunch':
                    this.lunchlist.create(currentFood)

                    if (currentBreakfast) {
                        this.breakfastlist.remove(currentBreakfast);
                    } else if (currentDinner) {
                        this.dinnerlist.remove(currentDinner);
                    } else if (currentSnack) {
                        this.snacklist.remove(currentSnack);
                    }
                    break;
                case 'Dinner':
                    this.dinnerlist.create(currentFood);

                    if (currentBreakfast) {
                        this.breakfastlist.remove(currentBreakfast);
                    } else if (currentLunch) {
                        this.lunchlist.remove(currentLunch);
                    } else if (currentSnack) {
                        this.snacklist.remove(currentSnack);
                    }
                    break;
                case 'Snack':
                    this.snacklist.create(currentFood);

                    if (currentBreakfast) {
                        this.breakfastlist.remove(currentBreakfast);
                    } else if (currentLunch) {
                        this.lunchlist.remove(currentLunch);
                    } else if (currentDinner) {
                        this.dinnerlist.remove(currentDinner);
                    }
                    break;
                default:
                    alert("Error: try again");

            }



        },

        removeClicked: function(e) {
            var $target = $(e.currentTarget).parent();
            var removeid = $target.attr('data-id');
            //tracks the models in all of the collections
            var modelRemoved = this.foods.get(removeid);
            var breakfastRemoved = this.breakfastlist.get(removeid);
            var lunchRemoved = this.lunchlist.get(removeid);
            var dinnerRemoved = this.dinnerlist.get(removeid);
            var snackRemoved = this.snacklist.get(removeid);

            this.foods.remove(modelRemoved);
            //remove the model if it exists in a collection
            if (breakfastRemoved) {
                this.breakfastlist.remove(breakfastRemoved);
            } else if (lunchRemoved) {
                this.lunchlist.remove(lunchRemoved);
            } else if (dinnerRemoved) {
                this.dinnerlist.remove(dinnerRemoved);
            } else if (snackRemoved) {
                this.snacklist.remove(snackRemoved);
            }
        },

        prepCollection: function() {
            var name = $('input').val();
            var newUrl = "https://api.nutritionix.com/v1_1/search/" + name + "?results=0%3A20&cal_min=0&cal_max=50000&fields=item_name,brand_name,item_id,nf_calories&appId=26952a04&appKey=33b9262901d0068d4895736b5af19805";

            //populate the collection with models and provide instruction html
            if (name == "") {
                this.$list.html("")
                this.$instruct.html("")
            } else {
                this.$instruct.html("Click On A Food Item To Track It");
                this.model.url = newUrl;
                this.model.fetch({
                    success: function(response, xhr) {
                        console.log("Inside success");
                        console.log(response.toJSON());
                    },
                    error: function(errorResponse) {
                        console.log(errorResponse)
                    }
                });
                this.listenTo(this.model, 'sync', this.render);
            }

        },

        track: function(e) {

            var $target = $(e.currentTarget);
            var item_name = $target.attr('data-name');
            var brand_name = $target.attr('data-brand');
            var calorieString = $target.attr('data-calories');
            var calorieAmt = parseFloat(calorieString);
            this.foodid = this.foodid + "1";

            var chooseday = '<form>What meal was this part of?: <select id="mySelect"> <option value="Breakfast">Breakfast</option><option value="Lunch">Lunch</option><option value="Dinner">Dinner</option><option value="Snack">Snack</option></select></form><button id="add" type="button">Add To Meal</button><button id="remove" type="button">Remove From Tracked</button>';

            var trackedhtml = '<li' + ' data-id=' + '"' + this.foodid + '"' + "<strong>" + item_name + '</strong>' + ' (' + brand_name + ')' + ' - ' + calorieAmt + ' Calories' + chooseday + '</li>'


            this.foods.create({
                id: this.foodid,
                title: item_name,
                brand: brand_name,
                calories: calorieAmt,
                html: trackedhtml
            });

        },

        rendertracked: function() {
            var total = 0;
            var trackedhtml = '';
            //resets the foodid variable when collection is empty to prevent long id names
            if (this.foods.length == 0) {
                this.foodid = ""
            };

            this.foods.each(function(food) {
                trackedhtml = trackedhtml + food.get('html');
                total += food.get('calories');
            }, this)
            this.$tracked.html(trackedhtml);
            this.$total.html(total);

        },
        renderbreakfast: function() {
            var total = 0;
            var breakfasthtml = '';

            this.breakfastlist.each(function(dish) {
                breakfasthtml = breakfasthtml + dish.get('html');
                total += dish.get('calories');
            }, this)
            $('#breakfast').html(breakfasthtml);
            $('#totalbreak span').html(total);


        },
        renderlunch: function() {
            var total = 0;
            var lunchtml = '';

            this.lunchlist.each(function(dish) {
                lunchtml = lunchtml + dish.get('html');
                total += dish.get('calories');
            }, this)
            $('#lunch').html(lunchtml);
            $('#totalunch span').html(total);
        },
        renderdinner: function() {
            var total = 0;
            var dinnerhtml = '';

            this.dinnerlist.each(function(dish) {
                dinnerhtml = dinnerhtml + dish.get('html');
                total += dish.get('calories');
            }, this)
            $('#dinner').html(dinnerhtml);
            $('#totaldinner span').html(total);
        },
        rendersnack: function() {
            var total = 0;
            var snackhtml = '';

            this.snacklist.each(function(dish) {
                snackhtml = snackhtml + dish.get('html');
                total += dish.get('calories');
            }, this)
            $('#snack').html(snackhtml);
            $('#totalsnack span').html(total);
        },

        render: function() {
            var terms = this.model;
            var wordhtml = '';
            terms.each(function(term) {
                wordhtml = wordhtml + '<li' + ' data-name=' + '"' + term.get('fields')['item_name'] + '"' + ' data-brand=' + '"' + term.get('fields')['brand_name'] + '"' + ' data-calories=' + '"' + term.get('fields')['nf_calories'] + '"' + '>' + "<strong>" + term.get('fields')["item_name"] + '</strong>' + ' (' + term.get('fields')["brand_name"] + ')' + ' - ' + term.get('fields')["nf_calories"] + ' Calories' + '</li>'
            }, this);
            this.$list.html(wordhtml);

        }
    });
    var app = new App();
});

这是我的HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>Food Guide App</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="css/main.css">
  </head>
  <body>

    <div class="text-center bg-black">
        <div class="container">
            <div class="row">
                <div class="col-xs-12">
                    <h1>Interactive Food Guide</h1>
                </div>
            </div>
        </div>
    </div>
    <div class="bg-blue">
        <div class="container">
            <div class="row">
                <div class="col-sm-6">
                    <h2>Food Search</h2>
                    <img class="img-responsive" src="img/my-food-guide-plate.jpg" alt="food plate photo">
                    <a name="foodsearch"></a>
                    <h4>Look up food here:</h4>
                    <input type="text" id="searchBox"> <br/><br/>
                    <p id="instruct"></p>
                    <ul class="spacefood" id="listing"></ul>
                    <a href="#foodtrack">Go to food tracking</a>
                    <p>
                        Go to:
                        <a href="#breakfastrack">Breakfast</a>&nbsp; &nbsp;
                        <a href="#lunchtrack">Lunch</a> &nbsp; &nbsp;
                        <a href="#dinnertrack">Dinner</a>&nbsp; &nbsp;
                        <a href="#snacktrack">Snack</a>&nbsp; &nbsp;
                    </p>
                </div>
                <div class="col-sm-6 top-space bottom-space">
                    <img class="img-responsive" src="img/foods.jpg" alt="foods">
                    <a name="foodtrack"></a>
                    <h2>Foods Tracked</h2>
                    <ul class="top-space spacetracked" id="tracked"></ul>
                    <p id="total"><strong> total calories:</strong> <span>0</span></p>
                    <a href="#foodsearch">Go to food search</a>
                    <p>
                        Go to:
                        <a href="#breakfastrack">Breakfast</a>&nbsp; &nbsp;
                        <a href="#lunchtrack">Lunch</a> &nbsp; &nbsp;
                        <a href="#dinnertrack">Dinner</a>&nbsp; &nbsp;
                        <a href="#snacktrack">Snack</a>&nbsp; &nbsp;
                    </p>
                </div>
            </div>
        </div>
    </div>

    <div class="bg-white">
        <div class="container">
            <div class="row">
                <div class="col-sm-6">
                    <a name="breakfastrack"></a>
                    <h1>Breakfast</h1>
                    <ul class="spacetracked" id="breakfast"></ul>
                    <p id="totalbreak"><strong> total calories:</strong> <span>0</span></p>
                    <a href="#foodsearch">Return to food search</a>
                    <p><a href="#foodtrack">Return to food tracking</a></p>
                    <p>
                        Go to:
                        <a href="#breakfastrack">Breakfast</a>&nbsp; &nbsp;
                        <a href="#lunchtrack">Lunch</a> &nbsp; &nbsp;
                        <a href="#dinnertrack">Dinner</a>&nbsp; &nbsp;
                        <a href="#snacktrack">Snack</a>&nbsp; &nbsp;
                    </p>
                </div>
                <div class="col-sm-6">
                    <img class="img-responsive" src="img/breakfast-meal.jpg" alt="breakfast plate photo">
                </div>
            </div>
        </div>
    </div>

    <div class="bg-blue">
        <div class="container">
            <div class="row">
                <div class="col-sm-6">
                    <a name="lunchtrack"></a>
                    <h1>Lunch</h1>
                    <ul class="spacetracked" id="lunch"></ul>
                    <p id="totalunch"><strong> total calories:</strong> <span>0</span></p>
                    <a href="#foodsearch">Return to food search</a>
                    <p><a href="#foodtrack">Return to food tracking</a></p>
                    <p>
                        Go to:
                        <a href="#breakfastrack">Breakfast</a>&nbsp; &nbsp;
                        <a href="#lunchtrack">Lunch</a> &nbsp; &nbsp;
                        <a href="#dinnertrack">Dinner</a>&nbsp; &nbsp;
                        <a href="#snacktrack">Snack</a>&nbsp; &nbsp;
                    </p>
                </div>
                <div class="col-sm-6">
                    <img class="img-responsive" src="img/lunch-meal.jpg" alt="lunch plate photo">
                </div>
            </div>
        </div>
    </div>

    <div class="bg-white">
        <div class="container">
            <div class="row">
                <div class="col-sm-6">
                    <a name="dinnertrack"></a>
                    <h1>Dinner</h1>
                    <ul class="spacetracked" id="dinner"></ul>
                    <p id="totaldinner"><strong> total calories:</strong> <span>0</span></p>
                    <a href="#foodsearch">Return to food search</a>
                    <p><a href="#foodtrack">Return to food tracking</a></p>
                    <p>
                        Go to:
                        <a href="#breakfastrack">Breakfast</a>&nbsp; &nbsp;
                        <a href="#lunchtrack">Lunch</a> &nbsp; &nbsp;
                        <a href="#dinnertrack">Dinner</a>&nbsp; &nbsp;
                        <a href="#snacktrack">Snack</a>&nbsp; &nbsp;
                    </p>
                </div>
                <div class="col-sm-6">
                    <img class="img-responsive" src="img/dinner-meal.jpg" alt="dinner plate photo">
                </div>
            </div>
        </div>
    </div>

    <div class="bg-blue">
        <div class="container">
            <div class="row">
                <div class="col-sm-6">
                    <a name="snacktrack"></a>
                    <h1>Snack</h1>
                    <ul class="spacetracked" id="snack"></ul>
                    <p id="totalsnack"><strong> total calories:</strong> <span>0</span></p>
                    <a href="#foodsearch">Return to food search</a>
                    <p><a href="#foodtrack">Return to food tracking</a></p>
                    <p>
                        Go to:
                        <a href="#breakfastrack">Breakfast</a>&nbsp; &nbsp;
                        <a href="#lunchtrack">Lunch</a> &nbsp; &nbsp;
                        <a href="#dinnertrack">Dinner</a>&nbsp; &nbsp;
                        <a href="#snacktrack">Snack</a>&nbsp; &nbsp;
                    </p>
                </div>
                <div class="col-sm-6">
                    <img class="img-responsive" src="img/snack-meal.jpg" alt="snack plate photo">
                </div>
            </div>
        </div>
    </div>

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

    <!-- Backbone and Underscore -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
    <!-- apps functionality -->
    <script src="js/app.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
    <!-- Firebase -->
    <script src="https://cdn.firebase.com/js/client/2.2.9/firebase.js"></script>
    <!-- BackboneFire -->
    <script src="https://cdn.firebase.com/libs/backbonefire/0.5.1/backbonefire.min.js"></script>
  </body>
</html>

1 个答案:

答案 0 :(得分:1)

基本上,您不必在index.html中拥有指向app.js文件的链接,而是必须在index.html中以正确的顺序包含每个文件。您可以像这样构建文件夹:

span

/js /models /collections /views 文件夹中,您可以将您的馆藏,模型放在/collections文件夹中,依此类推。可以将集合称为AllFoodsCollection.js和BreakfastCollection.js。然后你在index.html中引用它们。记得让你按正确的顺序分数。

/models

如果你使用像Gulp或Grunt这样的构建系统,它可以帮到你很多。使用Google's Web Starter Kit可以轻松开始。

看起来您还可以阅读一些关于如何构建骨干代码的正确教程。例如,当您要更改的是url属性时,您真的不需要所有这些集合。你可以有一个集合:

<script src="js/models/FoodModel.js"></script>    
<script src="js/collections/AllFoodsCollection.js"></script>
<script src="js/collections/BreakfastCollection.js"></script>

然后像这样实例化一个集合:

var FoodCollection = Backbone.Firebase.Collection.extend({
    model: Food,
    collectionType: '',
    url: function() { 
        "https://blinding-torch-8751.firebaseio.com/" + this.collectionType;
    }
});

有一本关于如何使用主干的好书,有很多关于如何构建代码的提示,在这里:http://addyosmani.github.io/backbone-fundamentals/

健康追踪器应用程序祝你好运:)。