我正在开发一个Backbone.js项目,我从Food API获得结果,然后显示它们。我可以点击结果列表中的某个项目并保存该结果,并将其显示在页面右侧的食物跟踪列表中。
食物跟踪列表显示有关食物(食物名称,品牌和卡路里)的信息以及所有跟踪食物的卡路里总量。
当您点击添加到用餐按钮时,应用程序也应该能够正常工作。
我的代码的新实现设计用于持续存储和收集每餐的总卡路里,为每餐创建一个单独的集合。
我认为这样可以让每个系列分别填充每个餐点,每个系列都可以加上它的卡路里。但是,当我点击搜索结果列表中的项目时,该项目将附加到所有膳食和跟踪食物列表中,而不仅仅是跟踪食物列表。
我已尝试过提供的解决方案,但我不知道如何创建多个firebase网址并在互联网上搜索此信息。
此外,添加到用餐功能时出现错误,因为我正在尝试删除并在addClicked函数中添加一个类。
这是jsfiddle
$(function() {
var Food = Backbone.Model.extend({
defaults: {
title: 'no information found',
brand: 'no information found',
calories: 'no information found',
day: 'all'
}
});
var AllFoods = Backbone.Firebase.Collection.extend({
model: Food,
url: "https://blinding-torch-8751.firebaseio.com/"
});
var Breakfast = Backbone.Firebase.Collection.extend({
model: Food,
url: "https://blinding-torch-8751.firebaseio.com/"
});
var Lunch = Backbone.Firebase.Collection.extend({
model: Food,
url: "https://blinding-torch-8751.firebaseio.com/"
});
var Dinner = Backbone.Firebase.Collection.extend({
model: Food,
url: "https://blinding-torch-8751.firebaseio.com/"
});
var Snack = Backbone.Firebase.Collection.extend({
model: Food,
url: "https://blinding-torch-8751.firebaseio.com/"
});
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() {
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.prepCollection = _.debounce(this.prepCollection, 1000);
this.$total = $('#total span');
this.$list = $('#listing');
this.$instruct = $('#instruct');
this.$tracked = $('#tracked');
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);
},
addClicked: function(e) {
var $target = $(e.currentTarget).parent();
var $selected = $target.find('#mySelect').val();
var mealClass= $target.attr('class');
var location = $target.attr('data-id');
var currentFood = this.foods.get(location);
var currenthtml = currentFood.get('html');
//replaces class in order to use it later to specifically target items in a specific meal collection
currenthtml.removeClass('alltracked').addClass($selected);
switch ($selected) {
case 'Breakfast':
this.breakfastlist.create(currentFood);
break;
case 'Lunch':
this.lunchlist.create(currentFood);
break;
case 'Dinner':
this.dinnerlist.create(currentFood)
break;
case 'Snack':
this.snacklist.create(currentFood)
break;
default:
alert("Error: try again");
}
},
removeClicked: function(e) {
var $target = $(e.currentTarget).parent();
var removeid = $target.attr('data-id');
$target.remove();
var modelRemoved = this.foods.get(removeid);
var addedClass = $target.attr('class');
this.foods.remove(modelRemoved);
//uses the added class to remove from the correct collection
switch (addedClass) {
case 'Breakfast':
this.breakfastlist.remove(modelRemoved);
break;
case 'Lunch':
this.lunchlist.remove(modelRemoved);
break;
case 'Dinner':
this.dinnerlist.remove(modelRemoved);
break;
case 'Snack':
this.snacklist.remove(modelRemoved);
break;
}
},
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";
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);
var foodid = $target.attr('data-id');
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=' + '"' + foodid + '"' + ' class="alltracked">' + "<strong>" + item_name + '</strong>' + ' (' + brand_name + ')' + ' - ' + calorieAmt + ' Calories' + chooseday + '</li>'
this.foods.create(new Food({
id: foodid,
title: item_name,
brand: brand_name,
calories: calorieAmt,
html: trackedhtml
}));
},
rendertracked: function() {
var total = 0;
var trackedhtml = '';
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').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').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').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').html(total);
},
render: function() {
var terms = this.model;
var wordhtml = '';
terms.each(function(term) {
wordhtml = wordhtml + '<li' + ' data-id=' + '"' + term.get('_id') + '"' + ' 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>
<a href="#lunchtrack">Lunch</a>
<a href="#dinnertrack">Dinner</a>
<a href="#snacktrack">Snack</a>
</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>
<a href="#lunchtrack">Lunch</a>
<a href="#dinnertrack">Dinner</a>
<a href="#snacktrack">Snack</a>
</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>
<a href="#lunchtrack">Lunch</a>
<a href="#dinnertrack">Dinner</a>
<a href="#snacktrack">Snack</a>
</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>
<a href="#lunchtrack">Lunch</a>
<a href="#dinnertrack">Dinner</a>
<a href="#snacktrack">Snack</a>
</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>
<a href="#lunchtrack">Lunch</a>
<a href="#dinnertrack">Dinner</a>
<a href="#snacktrack">Snack</a>
</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>
<a href="#lunchtrack">Lunch</a>
<a href="#dinnertrack">Dinner</a>
<a href="#snacktrack">Snack</a>
</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>
答案 0 :(得分:1)
您的收藏品需要有不同的网址。
var Foods = Backbone.Firebase.Collection.extend({
model: Food,
url: "https://blinding-torch-8751.firebaseio.com/foods",
});
var Breakfast = Backbone.Firebase.Collection.extend({
model: Food,
url: "https://blinding-torch-8751.firebaseio.com/breakfasts",
});
不相关,但在执行Backbone.Collection.create
时,您应该传递属性,而不是模型。 http://backbonejs.org/#Collection-create以下是一个例子:
this.foods.create({
id: foodid,
title: item_name,
});