2015-09-04 69 views
0

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

这里是我的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

你应该去require.js或almond.js只是谷歌它会得到很多页 –

回答

1

基本上,而不是一个链接到index.html中的app.js文件,你就必须在index.html中以正确的顺序包含每个文件。你可以组织你的文件夹,如下所示:

/js 
    /models 
    /collections 
    /views 

在你/collections文件夹,你会把你的收藏,在/models文件夹模式等。一个集合可以被称为AllFoodsCollection.js和BreakfastCollection.js。然后你在index.html中引用它们。请记住要按照正确的顺序分片。

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

如果您使用Gulp或Grunt等构建系统,它可以帮助您很多。您可以通过使用Google's Web Starter Kit获得简单的开始。

它看起来像你会得到很多关于如何构建骨干代码的正确教程。例如,当你正在改变的是url属性时,你确实不需要所有这些集合。你可以有一个集合:

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

然后实例的集合,像这样:

var breakfastCollection = new FoodCollection({collectionType: 'breakfast'}); 

有一个伟大的书如何使用骨干,有很多关于如何组织你的代码,在这里提示:http://addyosmani.github.io/backbone-fundamentals/

与健康跟踪应用程序:)祝你好运。

+0

我有想法创建一个集合,但无法实例化与url属性,所以我别无选择,只能做到这一点这条路。我也在许多网站上研究如何使用url属性实例化,但据说这是不可能的。 – RSB

+0

我想在你的例子实例化这种方式行不通 – RSB

+0

@RSB,也许试试这个: 'FoodCollection = Backbone.Firebase.Collection.extend({ 型号:食品, collectionType: '', 火力点:新的Firebase(“https://blinding-torch-8751.firebaseio.com/”this.collectionType), });' – mtl