html 上传Backbone Slim Framework http://www.ebizdesigner.com/item/52-backbonejs-mvc-app-tea-tree-part-
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了html 上传Backbone Slim Framework http://www.ebizdesigner.com/item/52-backbonejs-mvc-app-tea-tree-part-相关的知识,希望对你有一定的参考价值。
<?php
error_reporting(E_ALL);
if (move_uploaded_file($_FILES['file']['tmp_name'], '../images/' . $_FILES['file']['name'])) {
echo "ok";
} else {
header('HTTP', true, 500);
}
?>
// Models
window.Tea = Backbone.Model.extend({ // Specify a urlRoot when using a model outside
// of a collection (like when deleteTea), to enable the
// default url function to generate URLs based
// on the model id. "[urlRoot]/id"
urlRoot: "./api/teas",
defaults: {
"id": null,
"brand": "brand name",
"name": "tea name",
"serving": "serving",
"servings": 0,
"ingredients": "",
"description": "",
"picture": "blank-photo.jpg"
}
});
window.TeaCollection = Backbone.Collection.extend({
model: Tea,
// Set the url property (or function) on a collection
// to reference its location on the server.
url: "./api/teas"
});
// Views
window.TeaListView = Backbone.View.extend({
tagName: 'ul',
initialize: function() {
var self = this;
this.teaListItemViews = {}; // be triggered when new model created
// object.on(event, callback, [context]) Alias: bind
this.collection.on("add", function(tea) {
teaListItemView = new TeaListItemView({
model: tea
});
$(self.el).append(teaListItemView.render().el);
self.teaListItemViews[tea.cid] = teaListItemView;
});
this.collection.on("remove", function(tea, options) { // this == collection (has deleted models)
// self.$('[view-cid="' + model.cid + '"]').remove();
// $(self.el).remove('li#'+model.id);
self.teaListItemViews[tea.cid].close();
delete self.teaListItemViews[tea.cid];
});
},
// Override view default render function with your code
// that renders the view template from model data, and
// updates this.el with the new HTML.
render: function(eventName) { // Underscore function: _.each()
_.each(this.collection.models, function(tea) { // All views have a DOM element at all times
// which can be accessed by 'this.el'
$(this.el).append(new TeaListItemView({
model: tea
}).render().el);
}, this); // A good convention is to return this at the end of
// render to enable chained calls.
return this;
}
});
window.TeaListItemView = Backbone.View.extend({
tagName: "li",
template: _.template($('#tpl-tea-list-item').html()),
initialize: function() {
this.cid = this.model.cid;
this.model.on("change", this.render, this); //this.model.on("destroy", this.close, this);
},
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON())); // To identify the associated view of each model
// by model's instance reference (cid) rather attributes.
// $(this.el).attr('view-cid', this.model.cid);
return this;
},
close: function() { // Remove all callback functions
$(this.el).unbind(); // Remove the view from DOM
$(this.el).remove();
}
});
var TeaView = Backbone.View.extend({
template: _.template($('#tpl-tea-details').html()),
initialize: function() {
this.model.on("destroy", this.close, this); //this.model.on("change", this.render, this);
},
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
// Using delegateEvents provides a number of advantages
// over manually using jQuery to bind events to child
// elements during render.
// The Backbone events hash allows us to attach event
// listeners to either el-relative custom selectors, or
// directly to el if no selector is provided. An event takes
// the form of a key-value pair
// 'eventName selector': 'callbackFunction' and a number of
// DOM event-types are supported, including click, submit,
// mouseover, dblclick and more.
events: {
"click .save": "saveTea", // upload photo first,
// then save any change
"click .delete": "deleteTea",
"change #changephoto": "changePhoto", // listen changephoto event
"drop #teaphoto": "dropPhoto",
// listen drop events
"dragover #teaphoto": function(e) {
e.preventDefault();
}
},
saveTea: function() {
this.model.set({
name: $('#name').val(),
brand: $('#brand').val(),
serving: $('#serving').val(),
servings: $('#servings').val(),
ingredients: $('#ingredients').val(),
description: $('#description').val()
});
var self = this;
if (this.pictureFile) { //console.log( this.pictureFile.name);
this.model.set("picture", this.pictureFile.name); // append photo into FormData object
var fileData = new FormData();
fileData.append('file', this.pictureFile); // upload FormData object by XMLHttpRequest
$.ajax({
url: 'api/upload.php',
type: 'POST',
data: fileData,
processData: false,
cache: false,
contentType: false
}).done(function() {
console.log(self.pictureFile.name + ' uploaded successfully !');
}).fail(function() {
console.log('Error! An error occurred while uploading ' + self.pictureFile.name + ' !');
return false;
});
};
if (self.model.isNew()) { // Equivalent to instantiating a model with a hash of
// attributes, saving the model to the server, and adding
// the model to the set after being successfully created.
// Creating a model will trigger an immediate "add" event
// on the collection, a "request" event as the new model
// is sent to the server, as well as a "sync" event, once
// the server has responded with the successful creation
// of the model.
app.teaList.create(self.model, {
success: function() {
console.log('Successful create & save model (id: ' + self.model.id + ' )');
app.navigate('teas/' + self.model.id, false);
}
});
} else { // Save model to database (or alternative persistence layer),
// by delegating to Backbone.sync.
self.model.save();
console.log('Successful update model (id: ' + self.model.id + ' )');
}
return true;
},
deleteTea: function() { // Destroys the model on the server by delegating
// an HTTP DELETE request to Backbone.sync.
var self = this;
this.model.destroy({
success: function(model) { // delete new created model: id == null
console.log('Tea (' + self.model.id + ') deleted successfully'); // $(this.el).unbind();
// Remove the view from DOM
// $(this.el).remove();
// app.navigate('/', true);
}
});
self.close();
app.navigate('/', false);
return false;
},
changePhoto: function(event) { // Prevents the event from bubbling up the DOM tree.
event.stopPropagation(); // To prevent the browser default handling of the data:
// default is open as link on drop.
event.preventDefault();
var newFile = event.target.files[0];
if (!newFile.type.match(/image.*/i)) {
alert('Insert an image!');
} else {
this.pictureFile = newFile; // Read the image file from the local file system
// and display it in the img tag.
var reader = new FileReader();
reader.onloadend = function() {
$('#teaphoto').attr('src', reader.result);
};
reader.readAsDataURL(this.pictureFile);
}
return false;
},
dropPhoto: function(event) {
event.stopPropagation();
event.preventDefault();
var e = event.originalEvent; // The DataTransfer object holding the data.
e.dataTransfer.dropEffect = 'copy';
this.pictureFile = e.dataTransfer.files[0]; // Read the image file from the local file system
// and display it in the img tag.
var reader = new FileReader();
reader.onloadend = function() {
$('#teaphoto').attr('src', reader.result);
};
reader.readAsDataURL(this.pictureFile);
return false;
},
close: function() { // Remove all callback functions
$(this.el).unbind(); // Remove the view from DOM
$(this.el).remove();
}
});
window.HeaderView = Backbone.View.extend({
template: _.template($('#tpl-header').html()),
initialize: function() {
this.render();
},
render: function(eventName) {
$(this.el).html(this.template());
return this;
},
events: {
"click .new": "newTeaEvent"
},
newTeaEvent: function(event) {
app.navigate('teas/new', true);
return false;
}
});
// Router
var AppRouter = Backbone.Router.extend({
routes: {
"": "list",
"teas/new": "newTea",
"teas/:id": "teaDetails"
},
initialize: function() {
$('#header').html(new HeaderView().render().el);
},
list: function() {
this.teaList = new TeaCollection(); // When the model data returns from the server, it uses set to
// (intelligently) merge the fetched models, unless you pass
// {reset: true}, in which case the collection will be reset.
this.teaList.fetch(); // When creating a new View, the options passed,like model,
// collection, etc. are attached to the view as 'this.options'
// for future reference
this.teaListView = new TeaListView({
collection: this.teaList
});
$('#sidebar').html(this.teaListView.render().el);
},
teaDetails: function(id) {
this.tea = this.teaList.get(id);
this.teaView = new TeaView({
model: this.tea
});
$('#content').html(this.teaView.render().el);
},
newTea: function(event) { //if (app.teaView) app.teaView.close();
this.teaView = new TeaView({
model: new Tea()
});
$('#content').html(this.teaView.render().el);
return false;
}
});
var app = new AppRouter();
// When all of Routers have been created, and all routes are set up
// properly, call Backbone.history.start() to begin monitoring
// hashchange events, dispatching routes.
Backbone.history.start();
<pre class="brush: js">
<!DOCTYPE html>
<html>
<head>
<title>Backbone Tea Tree</title>
<link rel="stylesheet" href="/./css/styles.css" />
<script data-main="js/main" src="/lib/requirejs/require.js"></script>
<meta charset="utf-8" />
</head>
<body>
<section>
<header id="header" align="center">
<span class="title">Welcome to Backbone Tea Tree</span>
</header>
<nav id="nav"></nav>
<section id="content">
<article id="summary">
<h1>Backbone Tea Tree</h1>
<ol>
<li> is one MVC & single-page web app on Backbone.js </li>
<li> is one modular Backbone app which loading JS code as-needed by RequireJS </li>
<li> whenever the Model's data change, all the Views bound to this Model automatically re-render </li>
<li> integrate with RESTful services based on Slim framework (PHP version) </li>
<li> one Responsive Web Design (RWD) application by CSS3 Media Queries mechanics </li>
<li> to drag&drop image file and upload it to web server based on HTML 5 APIs: communication, drag & drop</li>
</ol>
</article>
</section>
</section>
<footer>
<small>Written by <a href="http://www.ebizdesigner.com/">John Yin</a></small>
</footer>
<!-- Templates -->
<script type="text/template" id="tpl-header">
<span class="title">Backbone Tea Navigation</span>
<button class="new">New Tea</button>
</script>
<script type="text/template" id="tpl-tea-list-item">
<p><a href="#teas/<%= id %>">
<img src="/./images/<%= picture %>" alt="<%= name %>" /></a></p>
</script>
<script type="text/template" id="tpl-tea-details">
<div class="form-left-col">
<img height="350" src="/./images/<%= picture %>" />
</div>
<div class="form-right-col">
<label>Id:</label>
<input type="text" id="id" name="id" value="<%= id %>" disabled />
<label>Name:</label>
<input type="text" id="name" name="name" value="<%= name %>" required/>
<label>Brand:</label>
<input type="text" id="brand" name="brand" value="<%= brand %>" required/>
<label>Serving:</label>
<input type="text" id="serving" name="serving" value="<%= serving %>" required/>
<label>Servings:</label>
<input type="text" id="servings" name="servings" value="<%= servings %>" />
<label>Ingredients:</label>
<textarea id="ingredients" name="ingredients">
<%=i ngredients %>
</textarea>
</div>
<div>
<label>Description:</label>
<textarea id="description" name="description">
<%=d escription %>
</textarea>
</div>
<button class="save">Save</button>
<button class="delete">Delete</button>
</script>
<!-- JavaScript -->
<script src="/lib/jquery-1.7.1.min.js"></script>
<script src="/lib/underscore-min.js"></script>
<script src="/lib/backbone-min.js"></script>
<script src="/js/main.js"></script>
</body>
</html>
</pre>
以上是关于html 上传Backbone Slim Framework http://www.ebizdesigner.com/item/52-backbonejs-mvc-app-tea-tree-part-的主要内容,如果未能解决你的问题,请参考以下文章
Backbone & Slim PHP - Access-Control-Allow-Headers - 可以获取信息,不能发布吗?
Backbone & Slim PHP - Access-Control-Allow-Headers - 可以获取信息,不能发布吗?
Backbone UI 和 CMS 后端:涉足 Restful CRUD
通过 Alamofire 上传文件并使用 Slim PHP 在服务器端检索它