0

検索フォームといくつかの結果を含む単純なバックボーン アプリケーションを構築しています。そうしたいです:

  • ユーザーが「order by」選択フィールドの値を変更し、URL と結果を適切に更新できるようにする
  • ユーザーが事前設定された URL を介して到着したときに正しい結果が表示され、選択されたフォーム要素が URL と結果に一致することを確認します。

使用する適切な制御フローを見つけたと思いますが、誰かに正気をチェックしてもらいたいです。基本的に、Views に URL を直接更新させ、Router が Model を更新する作業を行います。次に、他のビューがモデルをリッスンします。

問題なく動作しているように見えますが、ビューで手動で URL を作成し、ルーターで再度解析する必要があり、これは繰り返しのように感じます。したがって、これが Backbone での正しいやり方なのか、それとももっとうまくやれるのかを知ることができれば幸いです。

擬似コードは次のとおりです。

 User changes value of select to "price-asc"    
           |                                        
           |                                        
           v                                        
 Form view hears change event, and              
 updates the URL to #order-by-price-asc            
           |                                       
           |                                       
           v                                       
 Router looks at new route,        <----- User loads page, with 
  sets model value                       #order-by-price-asc route
           |
           |
           v   
  Results view hears change 
  to model value, loads in 
  new results via Ajax

コードは次のとおりです。

HTML:

<select id="order">
    <option value=''></option>
    <option value='price-asc'>price (low to high)</option>
    <option value='price-desc'>price (high to low)</option>
</select>
<div id="results"></div>

JS:

var SearchModel = Backbone.Model.extend({
    initialize: function() {
        this.bind("change:query", function() {
        this.performSearch();
        });
    },
    performSearch: function() {
        // Will eventually do Ajax search here, 
        // but for the moment, just bind to query. 
        this.set("results", this.get("query"));
    },
});

var SearchFormView = Backbone.View.extend({
    el: $('#order'),
    events: {
        "change": "updateURL"
    },
    initialize: function() {
        this.model.on("change:results", this.updateFormClasses, this);
    },
    updateFormClasses: function(model, query) {
        this.$el.val(query);
    },
    updateURL: function(e) {
        var url = '';
        ($('#order').val() !== '') ? url += "/by-" + $('#order').val() : null;
        SearchApp.navigate(url, {trigger: true});
    }
});

var SearchResultsView = Backbone.View.extend({
    el: "#results",
    initialize: function() {
        this.model.on("change:results", this.displayResults, this);
    },
    displayResults: function(model, query) {
        this.$el.text(query)
    }
});

var AppRouter = Backbone.Router.extend({
    routes: {
    "*str": "index",
    },
    initialize: function() {
        this.searchModel = new SearchModel();
        this.searchFormView = new SearchFormView({
            model: this.searchModel
        });
        this.searchResultsView = new SearchResultsView({
            model: this.searchModel
        });
    },
    index: function(str) {
        var ordering = str.match(/by-.*/gi);
        if (ordering !== null) {
            this.searchModel.set({"query": ordering[0].replace('by-','')});
        }
    }
});
var SearchApp = new AppRouter();
Backbone.history.start({});
4

1 に答える 1

1

実行できる最適化はいくつかあります。

  1. URLを手動で解析する代わりに、オプションのルートパラメータを使用します。

    var AppRouter = Backbone.Router.extend({
        routes: {
          "*str(/by-:sort)": "index",
        },
        index: function(str, sort) {
          if(sort) {
            //...
          }
        }
    });
    
  2. ルーターを経由するのではなく、ビューがモデルの変更を処理できるようにすることを検討してください。コードの重複を避けるために、このロジックをモデルメソッドにカプセル化します。

    var SearchModel = Backbone.Model.extend({
      sort: function(field) {
        this.set({query:field});
      }
    });
    
    var SearchFormView = Backbone.View.extend({
      el:"#order",
      events: {
        "change": "updateSort"
      },
      updateSort: function(e) {
        var sortOrder = this.$el.val();
    
        //update model
        this.model.sort(sortOrder);
    
        //navigate without trigger:true, will update the URL but not trigger route
        SearchApp.navigate(sortOrder ? "/by-" + sortOrder : "");
      }
    }    
    
    var AppRouter = Backbone.Router.extend({
        index: function(str, sort) {
          if(sort) {
            this.searchModel.sort(sort);
          }
        }
    }); 
    

view.elまた、宣言をに変更し、jQueryセレクターの代わりに#order要素を参照していることにも注意してください。this.$elこれらは無関係ですが、それでもベストプラクティスです。

于 2013-02-07T14:06:41.110 に答える