Last active
August 29, 2015 14:24
-
-
Save mike-gusiev/b7407777c0b44445993a to your computer and use it in GitHub Desktop.
CanJS tips
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log('Static and public methods:'); | |
var Todo = can.Construct({ | |
count: 0 | |
}, { | |
author: function () {return "Justin";} | |
}); | |
console.log(Todo.count); //static property (can use without object) | |
//public method | |
var todo = new Todo(); | |
console.log(todo.author()); | |
//privat methods | |
console.log('\nPrivat Methods:'); | |
var PrivateTodo = Todo({ | |
isPrivate: function () { | |
return true; | |
} | |
}); | |
var private = new PrivateTodo(); | |
console.log(private.isPrivate()); //private: true | |
console.log(private.author()); //public: Justin | |
console.log('\nInit method:'); | |
var Todo = can.Construct({ | |
count: 0 | |
}, { | |
init: function (name, author) { | |
this.name = name; | |
this.authorName = author; | |
this.constructor.count++; | |
}, | |
author: function () { | |
return this.authorName; | |
} | |
}); | |
var todo = new Todo('dishes', 'Justin'); | |
console.log(Todo.count); //static: 1 | |
console.log(todo.author()); //public: Justin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log('Observer pattern:'); | |
var paginate = new can.Observe({offset: 0, limit: 100, count: 2000}); | |
console.log( paginate.attr('limit') ); //public property: 100 | |
paginate.attr('offset', 100); //changing public property | |
console.log( paginate.attr('offset') ); //public: 100 | |
paginate.removeAttr('count'); | |
console.log('\nStart listening property changes:'); | |
paginate.bind('offset', function (ev, newVal, oldVal) { | |
console.log('New:', newVal, 'Old:', oldVal); | |
}); | |
paginate.attr('offset', 200); | |
console.log('\nNested data:'); | |
var user = new can.Observe({ | |
name: { | |
first: 'Justin', | |
last: 'Meyer' | |
} | |
}); | |
console.log( user.attr('name.first') ); //nested property: Justin | |
user.attr('hobbies', ['programming', 'party rocking']); | |
console.log(user.attr('hobbies.1')); //second item: party rocking | |
console.log('\nWorking with attr():'); | |
console.log(user.attr()); //return user object | |
user.attr({limit: 200, count: 1000}); //adding multiply properties | |
console.log( user.attr() ); | |
user.attr( {limit: 200}, true); //removes all values not present in the given object -> {limit: 200} | |
console.log( user.attr() ); | |
console.log('\nAny changes binding:'); | |
user.bind('change', function (ev, attr, how, newVal, oldVal) { | |
console.log('CHANGE:', attr, how, newVal, oldVal); | |
}); | |
user.attr('count', 2000); //fires event: "CHANGE: count add 2000 undefined" | |
user.attr('count', 3000); //fires event: "CHANGE: count add 3000 2000" | |
user.removeAttr('count'); //fires event: "CHANGE: count remove undefined 3000" | |
console.log('\nBinding handlers and unbinding:'); | |
var countHandler = function (ev, newVal, oldVal) { | |
console.log('the count has changed', newVal, oldVal); | |
} | |
user.bind('count', countHandler).attr('count', 3000); //fires 2 events! old global + new | |
user.unbind('count'); | |
user.attr('count', 2000); //fires 1 evet (global): CHANGE: count set 2000 3000 | |
console.log('\nEach function:'); | |
var paginate = new can.Observe({ | |
offset: 0, | |
limit: 100, | |
count: 1000 | |
}); | |
paginate.each(function (value, name) { | |
console.log(name, value); | |
}); | |
console.log('\nObserve Lists:'); | |
var hobbies = new can.Observe.List(['programming', 'basketball', 'party rocking']); | |
console.log(hobbies.attr(0)); //programming | |
hobbies.attr(0, 'eating mexicans'); | |
console.log( hobbies.attr() ); | |
var newindex = hobbies.indexOf('basketball'); | |
console.log(newindex); //1 | |
var lastElem = hobbies.pop(); //changes source array, deleting last elem | |
console.log(lastElem); //party rocking | |
console.log( hobbies.attr() ); | |
hobbies.push('guitar'); //adding elem at the end, returns array.length | |
console.log( hobbies.attr() ); | |
var firstElem = hobbies.shift(); //changes source array, deleting first elem | |
console.log(firstElem); //eating mexicans | |
console.log( hobbies.attr() ); | |
hobbies.unshift('football'); //returns array.length | |
console.log( hobbies.attr() ); | |
hobbies.splice(1, 1, 'flag football'); //removes second item and adds 'flag football' instead of it | |
console.log( hobbies.attr() ); | |
console.log('\nDifferent types of events:'); | |
hobbies | |
.bind('add', function (ev, newVals, index) { | |
console.log('ADD:', newVals, index); | |
}) | |
.bind('remove', function (ev, newVals, index) { | |
console.log('REMOVE:', newVals, index); | |
}) | |
.bind('set', function (ev, newVals, index) { | |
console.log('SET:', newVals, index); | |
}) | |
.bind('length', function (ev, length) { | |
console.log('LENGTH:', length); | |
}); | |
hobbies.pop(); //removes last item, fires 2 evets: remove and length |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log('can.Model for persisting data:'); | |
var Todo = can.Model({ | |
findAll : 'GET /todos', | |
findOne : 'GET /todos/{id}', | |
create : 'POST /todos', | |
update : 'PUT /todos/{id}', | |
destroy : 'DELETE /todos/{id}' | |
}, { | |
}); | |
//catching requests and return fake data | |
(function () { | |
var TODOS = [{ | |
id: 1, | |
name: 'do the dishes' | |
}, { | |
id: 2, | |
name: 'mow the lawn' | |
}, { | |
id: 3, | |
name: 'iron my shirts' | |
}]; | |
//findAll | |
can.fixture('GET /todos', function () { | |
return TODOS; | |
}); | |
//findOne | |
can.fixture('GET /todos/{id}', function (request) { | |
return TODOS[ (+request.data.id)-1 ]; | |
}); | |
//create | |
can.fixture('POST /todos', function (request) { | |
var id = TODOS.length + 1; | |
TODOS.push( $.extend( {id: id}, request.data )); | |
return {id: id}; | |
}); | |
//update | |
can.fixture('PUT /todos/{id}', function (request) { | |
$.extend( TODOS[ (+request.data.id) - 1 ], request.data ); | |
return {}; | |
}); | |
//delete | |
can.fixture('DELETE /todos/{id}', function (request) { | |
return {}; | |
}); | |
})(); | |
Todo.findAll({}, function (todos) { | |
console.log('\nFind All:'); | |
todos.each(function (todo) { | |
console.log(todo.name); | |
}); | |
}); | |
Todo.findOne({id: 1}, function (todo) { | |
console.log('\nFind One:'); | |
console.log(todo.name); | |
}) | |
var todo = new Todo({name: 'pick up milk'}); | |
todo.save(function (todo) { //save = update or create | |
console.log('\nCreate new item and saving to the model:'); | |
console.log(todo.name); | |
}); | |
setTimeout(function () { | |
console.log('\nModel bindings methods: '); | |
var todo = new Todo({name: 'canjs understanding'}); | |
todo.bind('name', function (ev, newVal, oldVal) { | |
console.log('name changed to:', newVal); | |
}); | |
todo.attr('name', 'new name'); | |
}, 1000); | |
setTimeout(function () { | |
console.log('\nBinding events on class and object:'); | |
var staticReport = function (ev, todo) { | |
console.log('some todo was', ev.type, ' named', todo.name); | |
} | |
var instanceReport = function (ev) { | |
console.log('my todo was', ev.type, ' named', this.name); | |
} | |
Todo.bind('created', staticReport) | |
.bind('updated', staticReport) | |
.bind('destroyed', staticReport); | |
var todo = new Todo({name: 'learn model events'}); | |
todo.bind('created', instanceReport) | |
.bind('updated', instanceReport) | |
.bind('destroyed', instanceReport); | |
todo.save(); //fires 2 create events. first from object, next from class | |
setTimeout(function () { | |
//updating | |
todo.attr('name', 'Learned model events'); | |
todo.save(); //fires 2 update events | |
}, 500); | |
setTimeout(function () { | |
todo.destroy(); //fires 2 destroy events | |
}, 1000); | |
setTimeout(function () { | |
new Todo({name: 'Temp'}).save(); //fires only 1 event!!! | |
}, 1500); | |
}, 2000); | |
setTimeout(function () { | |
console.log('\ncan.Model.List derived from findAll:'); | |
var globalTodos = {}; | |
Todo.findAll({}, function (todos) { | |
globalTodos = todos; | |
}); | |
setTimeout(function () { | |
globalTodos.bind('remove', function (ev, removed, index) { | |
console.log('removed', removed[0].name, 'at', index); | |
}); | |
globalTodos[0].destroy(); | |
}, 500); | |
}, 4000); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="ru"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Can JS</title> | |
</head> | |
<body> | |
<ul id="todos"></ul> | |
<script src="js/jquery-1.11.3.min.js"></script> | |
<script src="js/can.custom.js"></script> | |
<script src="js/extra.js"></script> | |
<script src="js/main.js"></script> | |
</body> | |
</html> | |
<!-- todo.ejs --> | |
<script id="todoEJS" type="text/ejs"> | |
<% for (var i =0; i < this.length; i++) { %> | |
<li><%= this[i].name %></li> | |
<% } %> | |
</script> | |
<!-- main.js --> | |
<script type="text/javascript"> | |
//catching requests and return fake data | |
(function () { | |
var TODOS = [{ | |
id: 1, | |
name: 'do the dishes' | |
}, { | |
id: 2, | |
name: 'mow the lawn' | |
}, { | |
id: 3, | |
name: 'iron my shirts' | |
}]; | |
//findAll | |
can.fixture('GET /todos', function () { | |
return TODOS; | |
}); | |
//findOne | |
can.fixture('GET /todos/{id}', function (request) { | |
return TODOS[ (+request.data.id)-1 ]; | |
}); | |
//create | |
can.fixture('POST /todos', function (request) { | |
var id = TODOS.length + 1; | |
TODOS.push( $.extend( {id: id}, request.data )); | |
return {id: id}; | |
}); | |
//update | |
can.fixture('PUT /todos/{id}', function (request) { | |
$.extend( TODOS[ (+request.data.id) - 1 ], request.data ); | |
return {}; | |
}); | |
//delete | |
can.fixture('DELETE /todos/{id}', function (request) { | |
return {}; | |
}); | |
})(); | |
var Todo = can.Model({ | |
findAll : 'GET /todos', | |
findOne : 'GET /todos/{id}', | |
create : 'POST /todos', | |
update : 'PUT /todos/{id}', | |
destroy : 'DELETE /todos/{id}' | |
}, {}); | |
Todo.findAll({}, function (todos) { | |
//var frag = can.view('todoEJS', todos); //byID | |
var frag = can.view('js/todo.ejs', todos); //byFilename | |
console.log(frag); | |
document.getElementById('todos') | |
.appendChild( frag ); | |
}); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log('\nDeferred object:'); | |
var deferred = new can.Deferred(); | |
deferred.then(function (value) { | |
console.log('I got', value); | |
}); | |
deferred.resolve('A VALUE'); | |
console.log('\nShowing template when all deferred objects are loaded:'); | |
can.view.ejs('favorites', '<%= todo1.name %> & <%= todo2.name %>'); | |
can.view('favorites', { | |
todo1: Todo.findOne({ id: 1 }), | |
todo2: Todo.findOne({ id: 2 }) | |
}) | |
.then(function (frag) { | |
document.body.appendChild( frag ); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
latest-video.hbs: | |
<script> | |
steal('modules/latest-video/', function(latestVideo){ | |
latestVideo('#{{id}}',{ | |
videoFeed: 'data/latest-video.json', | |
searchPage: '{{searchPage}}', | |
trailSize: 8 | |
}); | |
}) | |
</script> | |
latest-video.js: | |
define(['can', 'scripts/base-cloudinary', 'jspath', 'src/markups/blocks/card/card.hbs!'], function(can, BaseCloudinary, JSPath, VideoItemTemplate){ | |
return BaseCloudinary.extend({ | |
init: function () { | |
this._super(); | |
can.ajax({ | |
url: this.options.videoFeed, | |
dataType: 'json', | |
success: this.proxy(this.onFeedLoaded) | |
}); | |
this.initPropertes(); | |
if (!this.options.searchPage) { | |
this.prepareSearchControls(); | |
} | |
}, | |
... | |
'.b-filter__select change': function ($select, event) { | |
var searchTag = $select.val(); | |
this.currentTag = searchTag; | |
this.findVideo(searchTag, this.searchFilter); | |
}, | |
'.b-search__icon click': function ($icon, event) { | |
this.onSearchClick(); | |
}, | |
'.b-search__input keypress': function ($input, event) { | |
var key = event.keyCode || event.which; | |
if (key == 13) { | |
this.onSearchClick(); | |
} | |
}, | |
}) | |
}); | |
//feedapp.js: | |
var FeedApp = can.Control.extend({ | |
defaults: { | |
link: "http://api.massrelevance.com/MassRelDemo/kindle.json", | |
limit: 10, | |
interval: 10000 | |
}, | |
data: {}, | |
timer: false, | |
lastAjax: true | |
}, { | |
init: function () { | |
this.data = new can.List(); | |
this.view(); | |
this.startRefresh(); | |
}, | |
view: function () { | |
var mainHTML = can.view("app/tpl/main.tpl", { | |
data: this.data | |
}); | |
$(this.element).html(mainHTML); | |
}, | |
... | |
addNew: function (newData) { | |
var self = this; | |
can.batch.start(); | |
newData.map(function (item) { | |
self.data.unshift(item); | |
if(self.data.length > self.options.limit) self.data.pop(); | |
}); | |
can.batch.stop(); | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment