잘 짜여진 자바스크립트 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
? i18noption.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 웹사이트
by 月風
