backbone | chaplin | coffee tutotial實現

backbone | chaplin | coffee tutotial實現

前端MVC框架不少,angular處理DOM的方式比較特別,試用了下感受不太順手,backbone
以前學習過一次,因爲做者文檔寫的太爛,遇到各類坑放了一段時間,最近從新學習了
下,組織了下項目結構,分享一下。javascript

js使用coffee,本文由backbone 漸進到chaplin,介紹遇到的坑和學習方法。css

此文算我上篇博客現代前端開發小記的姊妹帖html

學習路線

首先看backbone, 而後纔是chaplin,看官方文檔是沒有用的,須要讀源碼

腳手架

本文中用到的代碼 chaplin腳手架前端

此項目能夠方便的初始化一個chaplin項目,與gh:paulmillr/brunch-with-chaplin腳手架不
同的是項目文件的組織結構java

教程

google backbone + coffee
第一個連接是這個教程git

那就根據這個來學習backbone,具體的教程就不細說了。github

把項目克隆下來後 git checkout last-backbone
或者若是你不會用git 直接下載release中的last-backbonechrome

具體的依賴安裝方式|運行方式請參照master 分支的README.mdsegmentfault

項目的文件結構

下圖是last-backbone這個commit時的文件結構,如今略有不一樣,app下每一個文件
夾都是一個模塊,每一個模塊都會有assets(寫html),initialize(new出各個view),
routes(backbone 路由),views(backbone view), views下有templates(hbs), styles(樣式)緩存

common模塊放各類基類,和會複用到的東西

app
├── assets
│   ├── images
│   └── index.html
├── common
│   ├── application.coffee
│   ├── config.coffee
│   ├── mediator.coffee
│   ├── mock.coffee
│   ├── models
│   │   └── base
│   │       ├── collection.coffee
│   │       └── model.coffee
│   └── views
│       ├── base
│       │   └── view.coffee
│       └── styles
│           └── application.styl
├── lib
│   ├── utils.coffee
│   └── view-helper.coffee
└── tutorial
    ├── assets
    │   └── README.md
    ├── controllers
    │   └── README.md
    ├── initialize.coffee
    ├── models
    │   ├── item.coffee
    │   └── list.coffee
    ├── routes.coffee
    └── views
        ├── home
        │   ├── item-view.coffee
        │   ├── list-view.coffee
        │   ├── styles
        │   │   └── item.styl
        │   └── templates
        │       └── README.md
        └── README.md

另外一個項目 保持更新

skill_issues

backbone相關頁面

backbone_issue

backbone的坑

backbone和chaplin最長遇到的問題就是view中沒找到具體的DOM,
記住一條金科玉律

el container 選中的DOM必須是在new這個view前已經存在的元素

修改頁面的dom使用render

注意,取屬性值的時候須要用雙引號,由於解釋器不識別單引號

$('ul').append "<li>item  #{@counter}</li>"

view el

el必須是**pre exist**,也就是在調用前必須存在此元素

View = require 'common/views/base/view'

module.exports = class ListView extends View

  el: '#test'

  initialize: ->
    _.bindAll @
    @render()

  render: ->
    $(@el).append('<ul><li>hello backbone</li></ul>')
    @

注意<script>require('/tutorial/initialize');</script>這一行須要寫在 id='test'
的元素後面,不然會找不到這個dom

<!doctype html>
<!--[if IE 8]>    <html class="no-js lt-ie9" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Brunch example application</title>
  <meta name="viewport" content="width=device-width">
  <link rel="stylesheet" href="/stylesheets/app.css">
  <script src="/javascripts/vendor.js"></script>
  <script src="/javascripts/app.js"></script>
</head>
<body>
    <header>
        <h1>title</h1>
        <p>p p p p</p>
    </header>
    <div id="test"></div>
    <script>require('/tutorial/initialize');</script>
</body>
</html>

backbone是沒有controllers的,所以chaplin在backbone的基礎上加上了controller
以及一些緩存等等

chaplin階段

git checkout master
或者直接下載最新的代碼

使用chaplin後有一些變化,以及用法

view

根據源碼
https://github.com/chaplinjs/chaplin/blob/master/src/chaplin/views/view.coffee

  • backbone view中的el如今爲container
    constructor: @el = @container if @container

  • autoRender是否在constructor裏面調用一次render
    constructor: @render() if @autoRender

不要在使用_bindAll會出現問題

item-view

item-view繼承自Chaplin.View,之前使用render添加dom,如今能夠直接使用
hbs模板,不過根據源碼getTemplateFunction必須重寫

* getTemplateFunction ->
    throw new Error 'View#getTemplateFunction must be overridden'

重寫成,能夠放在你自定義的View基類裏面

getTemplateFunction: ->
    @template

hbs模板使用雙括號引用model中的屬性 {{attr}}

list-view

與item-view相同,也是須要重寫getTemplateFunction
list view中的itemView指明具體的ItemView,當list view的collection中
有變化時會自動渲染dom,此例中的addItem在collection裏面調用add會處發
這個事件,注意container和listSelector的不一樣

源碼中listSelector的註釋:

# as the container of the item views. If you specify `listSelector`, the
# item views will be appended to this element. If empty, $el is used.
listSelector: null

例如本例子中的模板裏面有一個ul,注意listSelector是在本模板的dom中選擇,
即:

最初
<div id="test">listview會加在這裏</div>
加載listview後

<div id="test"><button ...><ul></ul></button></div>
若是listSelector爲 'div ul'會選不中這個ul的
使用ul才能夠選中

View = require 'common/views/base/view'
CollectionView = require 'common/views/base/collection-view'
List = require 'tutorial/models/list'
Item = require 'tutorial/models/item'
ItemView = require './item-view'

module.exports = class ListView extends CollectionView

  autoRender: true
  container: '#test'
  itemView: ItemView
  listSelector: 'ul'
  template: require './templates/list'

  events:
    'click button': 'addItem'

  initialize: ->
    @collection = new List
    @counter = 0
    super

  addItem: ->
    @counter++
    item = new Item
    item.set
      part2: "#{item.get 'part2'} #{@counter}"
    @collection.add item

模板list.hbs

<button class="pure-button pure-button-primary">Add List Item</button>
<ul></ul>
相關文章
相關標籤/搜索