2016-12-17 4 views
0

私のアプリはルータが変更されてから別のビューをレンダリングするように設計されていますが、他のビューオブジェクトを作成する方法についてはわかりません。backbone.jsで別のビューオブジェクトを設定する方法

router.js

var app = app || {}; 
(function() { 
    'use strict'; 
    var views = app.view = app.view || {}; 
    app.Router = Backbone.Router.extend({ 
     routes: { 
      '*home': 'homeRoute', 
      'about': 'aboutRoute', 
      'contact': 'contactRoute' 
     }, 
     initialize: function() { 
      // create the layout once here 
      this.layout = new views.Application({ 
       el: 'body', 
      }); 
     }, 
     homeRoute: function() { 
      var view = new views.Home(); 
      this.layout.setContent(view); 
     }, 
     aboutRoute: function() { 
      var view = new views.About(); 
      this.layout.setContent(view); 
     }, 
     contactRoute: function() { 
      var view = new views.Contact(); 
      this.layout.setContent(view); 
     } 
    }); 
})(); 

view.js

var app = app || {}; 
(function() { 
    'use strict'; 
    //views linitalize 
    var views = app.view = app.view || {}; 
    views.Application = Backbone.View.extend({ 
     initialize: function() { 
      // caching the jQuery object on init 
      this.$content = this.$('#content'); 
      this.$loading = this.$('#loading'); 
     }, 
     setContent: function(view) { 
      var content = this.content; 
      if (content) content.remove(); 
      this.showSpinner(); 
      content = this.content = view; 
      console.log(view); 
      //content rednering 
      this.$content.html(content.render().el, this.hideSpinner()); 
     }, 
     showSpinner: function() { 
      this.$loading.show(); 
     }, 
     hideSpinner: function() { 
      this.$loading.hide(); 
     }, 
    }); 
    views.Home = Backbone.View.extend({ }); 
    views.About = Backbone.View.extend({ 
     initialize: function(){ 
     this.render(); 
     }, 
     render: function(){ 
     var template = _.template("<strong>About page</strong>"); 
     } 
    }); 
    views.Contact = Backbone.View.extend({ 
     my_template: _.template("<strong>Contact page</strong>"); 
    }); 
})(); 

index.htmlを

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title></title> 
    </head> 
    <body> 
    <ul class="pills"> 
     <li><a href="#/">Home</a></li> 
     <li><a href="#/about">About</a></li> 
     <li><a href="#/contact">Contact</a></li> 
    </ul> 
    <div id="content"></div> 
    <div id="loading">load the page...</div> 
    <div id="sumMenu"></div> 
    <script src="lib/jquery-3.1.1.min.js"></script> 
    <script src="lib/underscore.js"></script> 
    <script src="lib/backbone.js"></script> 
    <script src="lib/backbone.localstorage.js"></script> 
    <script src="routers/router.js" ></script> 
    <script src="views/view.js" ></script> 
    <script src="views/app.js" ></script> 
    </body> 
</html> 

あなたはこのコードを見れば、あなたはよわかる。上記のことを伝えるのは難しいです。 view.js

見て、私は3つのビュープロパティ(homeaboutcontact)および実行されていないものを含まれているコードを書きました。

私は本当にオブジェクトの作成後に、オブジェクトの値とレンダリングを設定する方法を知りたいですか?

答えて

2

コードが重くmy other answerに触発されていますが、読みする必要がありますされBackbone documentation(ともUnderscore'sに何が起こっているのかを理解するために、何をやっているとそれに機能を追加するために行われる必要があります。さもなければ、あなたは常に作業コードから離れて、あなたが理解していない新しい混乱に漂うでしょう。

バックボーンのドキュメントは短くて甘く、source codeはコメントで埋められています。アンダースコアのドキュメントをすべて読んではいけませんが、少なくとも使用している機能のドキュメント(_.templateなど)を読んでください。


Router routes

あなたはそれが動作するかどうか最初に確認せずに私の他の回答から正確なコード、貼り付けコピーするので、あなたは私が作った間違いをコピーしました。 より具体的なルートを最初に定義し、キャッチオールルートを最後に指定する必要があります。

routes: { 
    'about': 'aboutRoute', 
    'contact': 'contactRoute', 
    // put the catch-all last 
    '*home': 'homeRoute', 
}, 

新しいルータをインスタンス化する場合、そのコンストラクタは、最初に、最後からのルートを解析した_bindRoutesを呼び出します。

_bindRoutes: function() { 
    if (!this.routes) return; 
    this.routes = _.result(this, 'routes'); 
    var route, routes = _.keys(this.routes); 
    while ((route = routes.pop()) != null) { 
    this.route(route, this.routes[route]); 
    } 
}, 

後添加ルートは、以前に宣言されたルートを無効にすることができます。


render function

次がどうなるどう思いますか?

render: function(){ 
    var template = _.template("<strong>About page</strong>"); 
} 

だから今やっていることすべてがある:

  • それは新しい関数を作成し、
  • template
  • という名前のローカル変数に代入しますし、他に何もしません。

あるいはこの:あなたはそれで何もしないならば、それは自分自身で何かをしないように、ビューの

my_template: _.template("<strong>Contact page</strong>"); 

my_templateプロパティは、標準のバックボーンではありません。理解する

、あなたがアンダー_.template関数は引数としてテンプレート文字列を取ります(必要に応じて設定オブジェクト)ことを知っておく必要があるとは、オブジェクトを引数として受け取り、新しいプリコンパイルされたテンプレート関数を返します。More info and examples

バックボーンビューのrender機能は、オーバーライドするために開発者に委ねられています。理想的には何かをレンダリングし、idempotentにする必要があります。

単純なビューは次のようになります。

views.About = Backbone.View.extend({ 
    template: _.template("<strong>About page</strong>"), 
    render: function() { 
     this.$el.html(this.template()); 
     return this; 
    } 
}); 

良い大会が チェーン通話を可能にするためにrenderの終わりにreturn thisにあります。

そして、あなたがこれを実行する必要がありますあなたのコード内のコールチェーン化しているので:

content.render().el 

をjQueryとel

は、なぜあなたはthis.hideSpinner()を渡すのですか?

this.$content.html(content.render().el, this.hideSpinner()); 

それは2番目のパラメータは意味をなさないようthis.hideSpinner()返された値を使用して、ビューのel#contentのdivのHTMLを変更んが。

jQuery's .html functionは、1つのパラメータをとります。


ローディングスピナーはどこに配置しますか?

同期DOM操作内ではありません。見られる前に取り除かれたスピナーを置くのは無駄です。

非同期読み込みがある場合はローディングスピナーが意味を持ちます。は、ページがクラッシュしなかったことや凍結していないことをユーザーに通知したいと考えています。

ホームページのニュースを読み込みたいとします。

コンソールで
homeRoute: function() { 
    console.log("showing the spinner"); 
    this.layout.showSpinner(); 

    var collection = new Backbone.Collection({ 
      url: "/you/api/url/for/latest/news" // simple example 
     }), 
     view = new views.Home({ 
      collection: collection 
     }); 

    collection.fetch({ 
     context: this, 
     success: function() { 
      console.log("removing the spinner"); 
      this.layout.hideSpinner(); 
      this.layout.setContent(view); 
     } 
    }); 

    console.log("End of homeRoute function"); 
}, 

、次の順序でログが表示されます:

showing the spinner 
End of homeRoute function 
removing the spinner 

詳しい情報は、以下を参照してください。

+0

ありがとうございました卿あなたの非常に親切:) 私はあなたの答えの上にいくつかの質問があります 私は** _ bindRoutes **を書き、それから建設コールは自動ロードですか? もレンダリングします**これを返す; **あまりにも? –

+0

@SeanSin '_bindRoutes'は、Backboneのルーターの「プライベート」機能です。これは、任意のルータコンストラクタで呼び出されます。私は参考に私の答えにそれを含めた。レンダリングで 'return this'をコンベンションにすると、私はこれに関するドキュメンテーションを引用しました。デフォルトの['render'](https://github.com/jashkenas/backbone/blob/7da4ed73e7402baf614a50a6551d47ace68b5239/backbone.js#L1348-L1353)はこれをデフォルトで行い、連鎖関数呼び出しを有効にします。 –

関連する問題