您的位置:首页 > Web前端 > JavaScript

Canjs 基础教程之技巧篇

2015-06-10 20:59 323 查看

Component

Template

Use the tag to position the custom element’s source HTML.

使用标签获取自定义标签元素的源HTML内容.

can.Component.extend({
tag: "hello-world",
template: "<h1><content/></h1>"
});


Html Template

<hello-world>Hi There</hello-world>


Html

<hello-world><h1>Hi There</h1></hello-world>


Using html attributes like can-EVENT-METHOD, you can directly call a scope method from a template

使用html属性类似can-click=’back’方式,可以在template中访问定义在scope中的back方法.

Template中使用{{}}访问scope中的属性或方法.

Scope

If you want to set the string value of the attribute on scope, give scope a default value of “@”.

默认使用’@’符号获取自定义标签的属性值

can.Component.extend({
tag: "hello-world",
template: "<h1>{{message}}</h1>",
scope: {
message: "@"
}
});


var template = can.mustache("<hello-world message='Howdy'/>");
template({})

<hello-world><h1>Howdy</h1></hello-world>


Scope也可以是一个function,但不常用.定义:function(attrs, parentScope, element)

attrs:custom element’s attributes(自定义标签元素的属性)

parentScope:(待理解)

element:自定义标签元素.

Events

A component’s events object is used as the prototype of a can.Control.

Component的Events对象被用作can.Control的原型属性.

The component’s scope is available within event handlers as this.scope.

在Events对象中使用this.scope.来访问Component的scope属性.

The events object can also listen to objects or properties on the component’s scope

Events对象同样可以监听Componet的scope对象的属性.

E.g.:监听scope的offset的属性变化,作相应的处理

can.Component.extend({
tag: "my-paginate",
template: "Page <span>1</span> <button class='next'>Next</button>",
scope: {
offset: 0,
page: function() {}
},
events: {
"{scope} offset": function() {
this.element.find("span").text(this.scope.page())
}
}
});


在Components的Event中可以绑定inserted 和removed事件,用于监听Component的Tag在页面中的插入和删除

Tag

Tag请用小写定义,大写时有时会有问题

Control

Creating a control instance:new can.Control( element, options )

var todosControl = new Todos( '#todos', {} );


element: is the NodeList consisting of the element the control is created on

options :merged with the control’s static defaults property

Templated Event Handlers

Customize event handler behavior with “{NAME}” in the event handler name

自定义事件行为:在event定义中使用{Name}

var Todos = can.Control.extend({
init: function( element , options ) { ... },
'li click': function( li ) { ... },
'li .destroy {destroyEvent}': function( el, ev ) { ... }
});
// create Todos with this.options.destroyEvent
new Todos( '#todos', { destroyEvent: 'mouseenter' } );


Values inside {NAME} are looked up on the control’s this.options first, and then the window.

{Name}中的值首先在control的this.options中查找,之后是window

E.g.:所以上面的例子,我们让他从window中查找:

var Todos = can.Control.extend({
init: function( element , options ) { ... },
'li click': function( li ) { ... },
'li .destroy {Events.destroy}': function( el, ev ) { ... }
});
Events = { destroy: 'click' };
// Events.destroy is looked up on the window.
new Todos( '#todos' );


If the value inside {NAME} is an object, Control will bind to that object to listen for events.

如果{Name}中的值是一个Object,Control将对一个该对象bind监听对应事件

var Tooltip = can.Control.extend({
'{window} click': function( el, ev ) {
// hide only if we clicked outside the tooltip
if ( !this.element.has( ev.target ) ) {
this.element.remove();
}
}
});


Defaults

Default options provided for when a new control is created without values set in options

Default Options 在新建一个Control对象时提供属性的默认值.

Message = can.Control.extend({
defaults: {
message: "Hello World"
}
}, {
init: function(){
this.element.text( this.options.message );
}
});
new Message( "#el1" ); //writes "Hello World"
new Message( "#el12", { message: "hi" } ); //writes hi


Processors

can.Control already has processors for these events:

can.Control 可处理的事件如下:

change、click、contextmenu、dblclick、focusin、focusout、keydown、keyup、keypress、mousedown、mouseenter、mouseleave、mousemove、mouseout、mouseover、mouseup、reset、resize、scroll、select、submit


Route

Route events will be triggered whenever the route changes to the route part the control is listening to

当can.control监听的route部分的属性变动时将会触发route事件

var Router = can.Control({
init : function(el, options) {
},
":type route" : function(data) {
// the route says anything but todo
},
"todo/:id route" : function(data) {
// the route says todo/[id]
// data.id is the id or default value
},
"route" : function(data){
// the route is empty(route为空时触发)
}
});
new Router(window);


Options

The this.options property is an Object that contains configuration data passed to a control when it is created (new can.Control(element, options))

This.options属性是一个在control创建是传递control的配置数据的Object

请查看Default中的示例代码!

Setup

Element

Map

Backup

can.Map.backup is a plugin that provides a dirty bit for properties on an Map, and lets you restore the original values of an Map’s properties after they are changed

var recipe = new can.Map({
title: 'Pancake Mix',
yields: '3 batches',
ingredients: [{
ingredient: 'flour',
quantity: '6 cups'
},{
ingredient: 'baking soda',
quantity: '1 1/2 teaspoons'
},{
ingredient: 'baking powder',
quantity: '3 teaspoons'
},{
ingredient: 'salt',
quantity: '1 tablespoon'
},{
ingredient: 'sugar',
quantity: '2 tablespoons'
}]
});
recipe.backup();
recipe.attr('title', 'Flapjack Mix');
recipe.title;     // 'Flapjack Mix'
recipe.isDirty(); // true
recipe.restore();
recipe.title;     // 'Pancake Mix'


Validations

The can/map/validations plugin provides validations on maps

Contact = can.Map.extend({
init : function(){
// validates that birthday is in the future
this.validate("birthday",function(birthday){
if(birthday > new Date){
return "your birthday needs to be in the past"
}
})
}
},{});
var contact = new Contact({birthday: new Date(2012,0) })


Use errors ( [attrs…], newVal ) to read errors or to test if setting a value would create an error:

使用errors方法测试设置的值是否验证通过

Listen to changes in data

Use Model.bind(eventType, handler(event, model)) to listen to all events of type on a model and model.bind(eventType, handler(event)) to listen to events on a specific instance

使用Model.bind(eventType, handler(event, model))来监听某Model类型的事件,使用model.bind(eventType, handler(event))来监听摸model对象的的事件

一般有created、updated、destroyed三个事件

// listen for when any todo is created
Todo.bind('created', function( ev, todo ) {...})
// listen for when a specific todo is created
var todo = new Todo({name: 'do dishes'})
todo.bind('created', function( ev ) {...})


Property Changes

// listen for when the name property changes
todo.bind('name', function(ev){  })


Listening with can.Control

Todos = can.Control.extend({
"{Todo} updated" : function(Todo, ev, todo) {...}
})


Parse Model

can.Model.parseModel(data, xhr)

Expected data format: {id: 1, name : “dishes”},If your service returns data like

{ thingsToDo: {name: “dishes”, id: 5} }

假如使用findOne接受的数据是:{ thingsToDo: {name: “dishes”, id: 5} },而model对应期望的数据是{id: 1, name : “dishes”}时,可以使用如下方式处理

Task = can.Model.extend({
parseModel: function(data){
return data.thingsToDo;
}
},{});


或者使用

Task = can.Model.extend({
parseModel: "thingsToDo"
},{});


Fixture

(待续)

Mustache

Register Helpers

Eg:创建一个通用的Link

can.mustache.registerHelper('link', function(text, url) {
text = can.esc(text);
url  = can.esc(url);
var result = '<a href="' + url + '">' + text + '</a>';
return can.mustache.safeString(result);
});


Iteration

迭代一组字符串数组

Template:
{{#people}}
{{.}}
{{/people}}
Data:
{
people: ["Andy", "Austin", "Justin"]
}
Result:
Andy Austin Justin


{{@index}}

The template:
<ul>
{{#each items}}
<li> {{@index}} - {{.}} </li>
{{/each}}
</ul>
Rendered with:
{ items: ['Josh', 'Eli', 'David'] }
Renders:
<ul>
<li> 0 - Josh </li>
<li> 1 - Eli </li>
<li> 2 - David </li>
</ul>


{{@key}}

The template:
<ul>
{{#each person}}
<li> {{@key}}: {{.}} </li>
{{/each}}
</ul>
Rendered with:
{ person: {name: 'Josh', age: 27, likes: 'Mustache, JavaScript, High Fives'} }
Renders:
<ul>
<li> name: Josh </li>
<li> age: 27 </li>
<li> likes: Mustache, JavaScript, High Fives </li>
</ul>


(待续)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: