2011-07-21 14 views
14

私のアプリケーションでコードを整理する方法として、今日backbone.jsを見てきました。Backbone.js - 既存のHTMLからモデル/ビューをインスタンス化する

私はの既存の htmlを使用してどのようにバックボーンモデル(およびビュー)を作成するのか疑問に思っていました(概念的には擬似コードで是非回答してください)。

私が見つけたすべてのチュートリアルは、空白のhtmlテンプレートを使用し、次にajaxを使用してコンテンツを注入することから構成されています。私はこれをしたくありません。

私には書籍のコレクションがあります。私はモデルとして各書籍の管理を開始したいと思います。この段階で

<!DOCTYPE HTML> 
<html lang="en-US"> 
<head> 
    <meta charset="UTF-8"> 
    <title>My Book Collection</title> 
</head> 
<body> 
    <head> 

    </head> 
    <body> 
     <ul id="bookCollection"> 
      <li class="book" data-book-id="1"><input type="text" name="book_1_name" value="My Book A"/></li> 
      <li class="book" data-book-id="2"><input type="text" name="book_2_name" value="My Book B"/></li> 
      <li class="book" data-book-id="3"><input type="text" name="book_3_name" value="My Book C"/></li> 
      <li class="book" data-book-id="4"><input type="text" name="book_4_name" value="My Book D"/></li> 
      <li class="book" data-book-id="5"><input type="text" name="book_5_name" value="My Book E"/></li> 
     </ul> 
    </body> 
</body> 
</html> 

、書籍名が変更されるたび機能(概念実証のための機能でちょうど警告)を呼び出し、その後、同期するURLを呼び出します私のデータベースでモデルに変更されます。

誰でもページ HTMLを既存のを使用して、上記実行する方法のために正しい方向に私を指すことができますか?

もし私がテンプレートを作るためにひげを使うことを計画しているのであれば違います。

+0

あなたがその目的のために、あなたのHTMLを変更する必要がある場合についての質問ですか?もしそうなら:本当に。それとも、JSが欲しいですか? –

+0

@ lazerscience - 私はちょうどそれは、データを引っ張って、データ+テンプレートを使用してhtmlを作成し、ページに注入するのではなく、既存のhtmlからビューを作成することが可能かどうかを知りたいですか?上記の例では、ループを作成する必要があります(私はjQueryを使用しています)、すべてのブック要素のビューを作成する必要がありますか? – calumbrodie

答えて

6

バックボーンのビューは、常に特定のhtml要素(ビューの属性el)にバインドされています。 BookCollectionViewul#bookCollectionに、BookViewli.bookにバインドされているようなものがあります。これは現在のテンプレート構造で問題ありません。

BookモデルをURLを使用してモデルにマップすることができます。モデルがそのURLからフェッチされ、モデル変更のイベント・バインディングを定義した場合、対応するビューは新しいモデル・データで更新されます。コレクションのURLと本のコレクションにも同じことが適用されます。

バックボーンについてはよく分かりませんが、http://liquidmedia.ca/blog/2011/02/backbone-js-part-3/またはhttp://www.jamesyu.org/2011/02/09/backbone.js-tutorial-with-rails-part-2/のようなものを勉強してください。もっと具体的な質問をすることができれば簡単だと思います!

+0

返事をありがとう。 「BookViewはli.bookにバインドされています。あなたの現在のテンプレート構造でうまくいくはずです。 1つのビューが5つの別々のアイテムにバインドされていることを意味しますか?これは受け入れられますか?これらの5つの項目を別々に追跡する必要はありませんか?広範な質問に申し訳ありません - 私は、ジャンプする前に関わっているコンセプトを把握しようとしています。 – calumbrodie

+0

別のビューインスタンスを各 'li'にバインドします! Evey時間は、ビュー内で定義されたすべてのイベントがビューの要素にバインドされるため、ビューが再レンダリングされるとすべてのイベントを定義する必要があります(バックボーンを使用する大きな利点の1つです.jQueryのライブほとんどの状況で) –

+0

あなたの助けてくれてありがとう - 近い将来にもっと愚かな質問は間違いありません – calumbrodie

15

私は本当に同じことをやろうとしていて、その周りに自分の道を見つけました!

私はすでにページ上にいくつかのtodosを持っていたtodoリストの例を構築しようとしていましたが、それらをTodosコレクションのモデルとして持ち込み、追加された要素と同じように管理したい空白のページ。

jsコード全体が要点として貼り付けられています。https://gist.github.com/1255736コメントを追加してください。

重要な部分は、コレクションをインスタンス化する方法です。基本的に:

  1. あなたはjQueryを通じて既存のhtml要素を取得します。モデルのビューがtagName: 'li'に基づいている場合、これはここで取得する必要がある種類のタグです。
  2. あなたはあなたがそれをモデルとベース要素を渡し、各モデルのビューを作成し、あなたのモデルを構成し、そこにいたデータをこすり、あなたのモデル
  3. を作成するために、これらのタグを反復処理。これは私が持っていた問題でした。私はビューを作成していて、それを後でmy_view.el = xxxを使って追加しようとしました。これは機能しません。
  4. あなたは注意コレクションに

をあなたのモデルを追加:collection.addを使用して、同様のビューを更新するように、コレクションは通常、後でビューに関連付けられています。 initializeはコンストラクタで呼び出されるので、コレクションはまだバインドされていないので、ここでそれらを追加することでHTMLの要素を複製することはありません。

// this is the important part for initializing from html! 
khepin.Todos = Backbone.Collection.extend({ 
    model: khepin.Todo, 

    // In this function we populate the list with existing html elements 
    initialize: function() { 
     _.each(
      // get all the <li></li> todo items (the base for the todo view) 
      // and for each of them: 
      $('.todo'), 
      function(a){ 
       // Create the model 
       var todo = new khepin.Todo(); 
       // Find the todo's text 
       var task = $(a).find('span')[0]; 
       task = $(task).text(); 
       // set the model correctly 
       todo.set({ 
        task: task 
       }); 
       // create the todo view 
       var todoView = new khepin.TodoView({ 
        model: todo, 
        el: a // the el has to be set here. I first tried calling new TodoView and setting the 'el' afterwards 
        // and the view wasn't managed properly. We set the "el' to be the <li></li> we got from jQuery 
      }); 
     // Add this new model to the collection 
     this.add(todo); 
     }, 
     this 
    ); 
} 
}) 

これが役に立ちます。

2

私はメインのビュー(ulリスト)のコンストラクタ内で同じ問題を抱えており、これをバックボーン0.9のように解決しました。

私はcoffeescriptの構文から私の心の中にそれを変換しましたので、いくつかの構文エラーがある場合は穏やかにしてください。

myListView = Backbone.View.extend({ 
    initialize: function() { 
     ._each(this.$el.children(), function(book, i) { 
      new Backbone.View({ 
        el: book, 
        model: this.collection.at(i) 
      }); 
     }); 
    } 
}); 

とこのようにそれを呼び出す:

new myListView({ 
    collection: anExistingCollection, 
    el: $('#bookCollection') 
}); 

それは、この例では、同じ指標に依存しているとしてコレクション「anExistingCollection」の順序はあなたの既に生成されたリストのエントリと同じであることが重要です。

(未テスト)

関連する問題