잘 짜여진 자바스크립트 MVC 프레임워크. Canjs

Backbone, AngularJS, Spine….
그동안 나왔던 자바스크립트 프레임워크를 조금씩 건드려는 보았지만,
항상 아쉬움이 남았습니다.
이번에 Canjs를 써보니, 정말 잘 만들어진 프레임워크라는 생각이 들어요.
자바스크립트MVC 프레임워크를 써 볼까 생각 중이시라면, Canjs 한번 고려해 보세요.

can.Control

컨트롤러에서 이벤트 처리

"li .destroy {Event.destroy}": function( el, event) {
var todo = el.closet('li').data('todo);
todo.destroy();
event.stopPropagation();}
});
Events = {destroy : "click"};

css Selector, html.getElementBy, $(selector)가 Control의 셀렉터로 사용된다.

When the element your Control is bound to is removed from the DOM,
the Control destroys itself, cleaning up any bound event handlers.

can.Control 이 아는 이벤트.
* change
* click
* contextmenu
* dblclick
* focusin
* focusout
* keydown
* keyup
* keypress
* mousedown
* mouseenter
* mouseleave
* mousemove
* mouseout
* mouseover
* mouseup
* reset
* resize
* scroll
* select
* submit

링크 처리 방법(How can I make a link in Canjs?)

레이어(layer)
<a id="id" href="javascript://">href</a>

페이지(page)
<a id="id" href="#!id">href</a>

무스타치에서 콜백 받기(Mustache Element Callback)

{{data 'model'}}

경로 설정(RequireJS Paths)

requireJS can require is /can
requireJS에서 canJS를 쓸 땐 can.js를 패스로 잡고 사용해야 한다.
registerHelper이용을 위해서는 can/view/mustache가 필요하다.

404루트 잡기(How to define a catch all route to handle 404 in can js?)

http://stackoverflow.com/questions/13824665/how-to-define-a-catch-all-route-to-handle-404-in-can-js

can.route.bind('change', function(ev, newVal) {
if (newVal === 'route') {
var valid = false;
$.each(can.route.routes, function(k,v) {
if (new RegExp(v.test).test(window.location.hash)){
valid = true;
return; //exit loop
}
})
if (!valid) {
//handle the false route here
}
}
});

다국어 지원(Localization)

Localization is a good example of a custom helper you might implement in your application. The below example takes a given key and returns the localized value using jQuery Globalize.

1. Mustache.registerHelper('l10n', function(str, options){
2. return Globalize != undefined
3. ? Globalize.localize(str)
4. : str;
5. });

can.route에서 i18next 데이터를 받아오지 못할 때

can.when을 이용하여 초기화가 된 후 can라우팅 처리를 해 준다.


var lang =utils.getParam('lang');
var i18noption = {debug: true};
lang != undefined
? i18n
option.lng = lang
: i18n_option.lng = "en";
can.when(i18n.init(i18n_option)).then(function (){});

모델 관계(model associations)

https://forum.javascriptmvc.com/topic/questions-about-model-associations

<div class="header">
<h1>Association</h1>
</div>
<!-- YOUR CODE HERE -->
<div id="contacts"></div>

can.fixture("/contacts.json", function(){
return [{
'id': 1,
'name' : 'Justin Meyer',
'birthday': '1982-10-20',
tasks : [{
id: 1,
title: "write up model layer",
due: "2010-10-5"
}]},{
'id': 2,
'name' : 'Brian Moschel',
'birthday': '1983-11-10',
tasks : [{
id: 2,
title: "write up funcunit",
due: "2009-5-1"
},{
id: 3,
title: "test funcunit",
due: "2010-3-15"}]
},{
'id': 3,
'name' : 'Bobby Joe',
'birthday': '1980-2-10'
}];
})

can.Model.convert.date = function(raw){
if(typeof raw == 'string'){
var matches = raw.match(/(\d+)-(\d+)-(\d+)/);
return new Date( +matches[1],
(+matches[2])-1,
+matches[3] );
}else if(raw instanceof Date){
return raw;
}
};

// A task model that has a date
can.Model("Task",{
attributes : {
due : 'date',
}
},{
weeksPastDue : function(){
return Math.round( (new Date() - this.due) /
(1000*60*60*24*7 ) );
}
});

// A contact model that has many tasks
can.Model("Contact",{
attributes : {
birthday : 'date',
tasks: "Task.models"
},
findAll : "/contacts.json"
},{
ageThisYear : function(){
return new Date().getFullYear() -
this.birthday.getFullYear()
},
getBirthday : function(){
return ""+this.birthday.getFullYear()+
"-"+(this.birthday.getMonth()+1)+
"-"+this.birthday.getDate();
}
});

// Get all contacts and put them on the page
Contact.findAll({},function(contacts){
var contactsEl = can.$('#contacts');

can.each(contacts, function(contact){
var li = can.$('<li>')
.html(contact.name + " "+ contact.ageThisYear())
.appendTo(contactsEl);

var ul = can.$("<ul>");
var tasks = contact.attr('tasks')

if(tasks){
tasks.each(function(){
this.attr('contact', contact);
ul.append('<li>'+this.title+" "
+this.weeksPastDue()+' contact: '+ this.attr('contact.name') +'</li>')
});
}

ul.appendTo(li)
});
});

 

Canjs 웹사이트