Home  >  Article  >  Web Front-end  >  Detailed explanation of front-end lightweight MVC framework CanJS_Others

Detailed explanation of front-end lightweight MVC framework CanJS_Others

WBOY
WBOYOriginal
2016-05-16 16:35:261637browse

Choose the right library

Creating a JS APP without good tools is very difficult. jQuery is just a library for operating DOM and does not provide any basis for creating APPs. This is why we need a specialized library like CanJS.

CanJS is a lightweight MVC library that provides you with the tools you need to create a JS APP.

CanJS is a lightweight MVC library that provides you with the tools you need to create a JS APP. It provides the basic framework of the MVC (Model-View-Control) pattern, template dynamic binding, route support and memory safety. It also supports jQuery, Zepto, Mootools, YUI, Dojo, and has a wealth of extensions and plug-ins.

In the first part you will learn:
Create a Control layer and a View layer (UI template) to display contacts
Use the Model model layer to represent data
Use fixtures plug-in to simulate ajax return data
You must be excited! Let’s start coding.
Create your folders and HTML
You first create a folder for your APP, and then create 4 subfolders under the directory: css, js, views and img. As follows:
contacts_manager
css
js
views
img

Save the following code as index.html:

Copy code The code is as follows:





CanJS Contacts Manager






                                                                                                                                                                                                                                                                                                                                   


                                                                                                                            

                                       
                                                                                                                                                                                                

                                                              

                                  

                                                                                       






At the bottom of the page you load the required JS (including your APP: contacts.js).
The CSS and image files used in the tutorial are available for download.

Use View to build your UI

View is the UI template used to render your APP. CanJS supports multiple template engines. This article uses EJS. CanJS includes and supports dynamic binding.
The tags of EJS templates are very similar to HTML and support the inclusion of JS code. The three commonly used tags are as follows:
<% CODE %>%20Execute%20JS%0A<%= CODE %>%20Execute%20JS%20and%20write%20the%20unescaped%20result%20to%20the%20HTML%20at%20the%20current%20location%0A<%== CODE %>%20Execute%20JS%20and%20write%20the%20escaped%20result%20to%20the%20HTML%20at%20the%20current%20position%20(for%20sub-templates).%0ATemplates%20can%20be%20loaded%20from%20files%20or%20script%20tags.%20This%20tutorial%20loads%20from%20EJS%20files.%20%0A

%0A

Show%20Contacts%0A

%0A

To%20create%20contacts,%20you%20must%20first%20create%20an%20EJS%20template%20and%20save%20the%20following%20code%20as%20contactsList.ejs%20into%20your%20views%20folder:%20

%0A

Copy code The code is as follows:



    <% list(contacts, function(contact){ %>
  • el.data('contact', contact) %>>
             <%== can.view.render('views/contactView.ejs', {
    Contact: contact, categories: categories
    }) %>

  • <% }) %>

contactLists.ejs will render a contact list, let’s analyze this template:

Copy code The code is as follows:

<% list(contacts, function(contact){ %>

If the callback method in the list() method is used with a list configured with an observer, once the data in the list changes, it will be called repeatedly using dynamic binding.

Copy code The code is as follows:

  • el.data('contact', contact) %>>
  • The above code generates a

  • with contact data through the element's callback method. After the method after the arrow is executed, the data of the el object is set to the corresponding element.

    Copy code The code is as follows:

    <%== can.view.render('views/contactView.ejs', {
    contact: contact, categories: categories
    }) %>

    The above code renders the sub-template contactView.ejs into a contact. can.view.render() returns HTML with template and data as parameters.

    Rendering a single contact

    Subtemplates are a great way to organize views into manageable chunks. Also makes your templates simple and easy to reuse. This template will be used later in the tutorial to create contacts. Save the following code as contactView.ejs into the views folder:

    Copy code The code is as follows:




     

       
     

     

              <%= contact.attr('name') ? "value='" contact.name "'" : "class='empty'" %>>
       
     

     

       
              <%= contact.attr('address') ? "value='" contact.address "'" : "class='empty'" %>>
       
              <%= contact.attr('phone') ? "value='" contact.phone "'" : "class='empty'" %>>
       
              <%= contact.attr('email') ? "value='" contact.email "'" : "class='empty'" %>>
     



    联系人的属性都放入了 标签里,这就可以编辑更新用户的资料。

    活化你的View(好文艺。。)

    EJS 处理模板过程中如果有用到attr() ,它周围的代码将会交由事件处理器管理,监听对应属性的变化,当属性发生变化,APP中关联的UI将会被更新。这功能利益于模板动态绑定机制,EJS的动态绑定是有选择性的,只有使用了attr()时才会为对应的属性开启。
    我们通过 contactView.ejs 中一个标签来了解它的用法:

    复制代码 代码如下:

      <%= contact.attr('name') ? "value='" contact.name "'" : "class='empty'" %>>

    特殊标记里的代码将转变成事件绑定到此联系人的name属性上。当name属性发生变化,事件将被触发同时HTML结构会被更新。

    使用can.Control来处理业务逻辑

    can.Control 创建了一个可组织,内在无泄漏,全权控制器,能用来创建widget或者处理业务逻辑。你通过所需要数据为一个DOM元素创建一个Control实例,可以在你的Control中定义方法绑定事件。
    当 Control 所关联的元素从DOM被删除时,Contol会自去销毁自己,同时清除所绑定的方法。
    要创建一个 Control,通过传入你定义的包含有函数的对象给 can.Control() 来实现继承。接下来事件也给传进去了。
    每个Contol实例都有几个重要的值和方法规范:
    this –  Control 实例的引用
    this.element – 实例中你所创建的DOM 元素
    this.options – 创建实例所需要的参数对象
    init() – 当实例创建成功时被调用

    管理联系人

    将以下代码片段添加到contacts.js 文件来创建管理联系人的Control:

    复制代码 代码如下:

    Contacts = can.Control({
    init: function(){
    This.element.html(can.view('views/contactsList.ejs', {
    Contacts: this.options.contacts,
    Categories: this.options.categories
    }));
    }
    })

    When an instance of Contacts is created, init() does two things:
    Use can.view() to render the contact. can.view() receives two parameters: a file or stript tag containing template and data; it will return a documentFragment (a lightweight container that manages DOM elements).
    Use jQuery.html() to insert the documentFragment of can.view() into the Control element

    Use Model to represent data

    Model is the abstraction layer of APP data. This APP uses two Models: one corresponding to contacts and one corresponding to categories. Add the following code to contacts.js:

    Copy code The code is as follows:

    Contact = can.Model({
    findAll: 'GET /contacts',
    create : "POST /contacts",
    update : "PUT /contacts/{id}",
    destroy : "DELETE /contacts/{id}"
    },{});

    Category = can.Model({
    findAll: 'GET /categories'
    },{});

    A model has 5 methods that may be defined to CRUD data, namely findAll, findOne, create, update and destroy. You can override these methods, but the best way is to use REST services (Representational State Transfer). As in the above code, you can safely ignore the static methods that will not be used in the APP.

    The important thing to point out here is that model instances are actually ‘observables’ derived from CanJS. can.Observe provides the observer mode for objects. can.Observe.List provides the observation mode for arrays. This means that you can get and set data through attr(), while monitoring data changes.
    The findAll() method returns a Model.list, which is the event triggered by can.Observe.List when an element is added or removed.

    Use Fixture to imitate Rest

    Fixture intercepts AJAX requests and simulates responses through files or methods. This is useful for testing, or when the backend is not ready yet. Fixture is what the APP model needs to simulate REST.
    First, you need to prepare some data for the fixture and add the following code to:

    Copy code The code is as follows:

    var CONTACTS = [
    {
    id: 1,
    name: 'William',
    Address: '1 CanJS Way',
    Email: 'william@husker.com',
    Phone: '0123456789',
    Category: 'co-workers'
    },
    {
    id: 2,
    name: 'Laura',
    Address: '1 CanJS Way',
    Email: 'laura@starbuck.com',
    Phone: '0123456789',
    Category: 'friends'
    },
    {
    id: 3,
    name: 'Lee',
    Address: '1 CanJS Way',
    Email: 'lee@apollo.com',
    Phone: '0123456789',
    Category: 'family'
    }
    ];

    var CATEGORIES = [
    {
    id: 1,
    name: 'Family',
    Data: 'family'
    },
    {
    id: 2,
    name: 'Friends',
    Data: 'friends'
    },
    {
    id: 3,
    name: 'Co-workers',
    Data: 'co-workers'
    }
    ];

    Once you have the data, connect it to a fixture to simulate REST. can.fixture() receives two parameters. The URL we want to intercept and the file and method we use to respond. Usually the URLs you want to intercept are dynamic and follow a pattern. Just add wildcard characters enclosed in {} to the URL.

    Add the following code to contacts.js:

    Copy code The code is as follows:

    can.fixture('GET /contacts', function(){
    return [CONTACTS];
    });

    var id= 4;
    can.fixture("POST /contacts", function(){
    return {id: (id )}
    });

    can.fixture("PUT /contacts/{id}", function(){
    return {};
    });

    can.fixture("DELETE /contacts/{id}", function(){
    return {};
    });

    can.fixture('GET /categories', function(){
    return [CATEGORIES];
    });

    The first four fixtures simulate the GET, POST, PUT and DELETE responses of the Contact model, and the fifth fixture simulates the GET response of the Category model.

    Launch APP

    Your APP has a Model to manage data, a View to render contacts, and a Control to organize it all. All you have to do now is launch the APP. Now you need to kickstart the application!
    Add the following code to contacts.js:

    Copy code The code is as follows:

    $(document).ready(function(){
    $.when(Category.findAll(), Contact.findAll()).then(
    Function(categoryResponse, contactResponse){
    var categories = categoryResponse[0],
    Contacts = contactResponse[0];

    new Contacts('#contacts', {
            contacts: contacts,
    categories: categories
    });
    });
    });

    Let’s analyze this code:

    Copy code The code is as follows:

    $(document).ready(function(){

    Use the jQuery.ready method to monitor the readiness of the DOM.

    Copy code The code is as follows:

    $.when(Category.findAll(), Contact.findAll()).then(
    function(categoryResponse, contactResponse){

    Call the findAll() methods of the two Models to obtain the types of all contacts. Since findAll() has a delay, $.when() ensures that both requests are completed at the same time before executing the callback method.

    Copy code The code is as follows:

    var categories = categoryResponse[0],
    contacts = contactResponse[0];

    Get the data set corresponding to the Model instance from the two findAll() methods. Is the first element of the array returned by the response.

    Copy code The code is as follows:

    new Contacts('#contacts', {
    contacts: contacts,
    categories: categories
    });

    Create a Control for Contact for the #contacts element. Contact and type data sets are passed into Control.
    Open your APP with a browser, you will see the following contact list:

    Summary

    This is the first article in the tutorial series. You already understand the core of CanJS:
    Models An abstraction layer for your APP data
    Views Templates that convert data into HTML
    Controls organizes everything

  • Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn