2

私は Backbone.js の初心者ですが、jQuery は大好きです。しかし、Backbone がコードをモデル、ビュー、およびコレクションに編成する方法は気に入っていますが、JS コードを作成するときに Backbone をどのように使用するかについてはまだ理解できません。

たとえば、ユーザーが入力ボックスに入力したときに提案ボックスを追加する、jQuery で書いた次の単純なコードを見てください。

// this is the model
var questions = [
    {question: "what is your name"},
    {question: "How old are you"},
    {question: "what is your mothers name"},
    {question: "where do work/or study"}
];

// search data function
function searchData(datas,term){
    return _.filter(datas, function(obj) {
        return ~obj.question.toLowerCase().indexOf(term);
    });
}

// Events
$("#suggestinput").on({
    keyup: function(){
        var results = searchData(questions, this.value);
        $("#suggestions")
            .addClass("active")
            .html(_.reduce(results, function(last, q){
                return last + "<p>" + q.question + "</p>";
             }, ""));
    },
    blur: function () {
        $("#suggestions").removeClass('active');
        $("#suggestions").html(" ");
    },
    focus: function () {
        if ( $(this).val() === "" ) {
            $("#suggestions").addClass('active');
            $("#suggestions").html("<p> start typing a question </p>");
        }
    }
});

Backbone.js 構造を使用して、このようなミニ機能を構築するためのアドバイスはありますか? コード全体を書くように言っているわけではありません。大まかなガイドラインや説明をいただければ幸いです。

JSFiddle にもこのコードの実例があります: http://jsfiddle.net/X8geT/1/

4

1 に答える 1

4

免責事項: バックボーンのソリューションと同様に、特定の問題に対処する方法は複数あります。次の回答はおそらく完全にやり過ぎであり、十分な注意を払う必要があります。

モデルを定義する

これらは、データとその処理方法を表します。ここでは、質問モデル (空ですが、わかりません)、質問コレクション (用語のフィルタリングが定義されている場所)、および現在の用語と一致する質問を格納する役割を担う検索状態コントローラーを定義します。

var Question = Backbone.Model.extend();

var Questions = Backbone.Collection.extend({
    model: Question,
    matches: function (term) {
        if (term==="")
            return [];

        term = term.toLowerCase();
        return this.filter(function(model) {
            return model.get('question').toLowerCase().indexOf(term)!==-1
        });
    }
});

var QuestionController = Backbone.Model.extend({
    defaults: {
        term: ""
    },
    initialize: function(opts) {
        this.questions = opts.questions; //known questions
        this.matches = new Questions();  //filtered questions

        //when the term changes, update the matches
        this.on('change:term', function (model, term) {
            this.matches.reset(this.questions.matches(term));
        }, this);
    }
});

ビューを定義する

それらは DOM 内のモデルの状態を表示し、ユーザーとの対話を処理します。入力を処理する SearchView と、現在の提案を表示する SuggestionsView を用意しましょう。

var SearchView = Backbone.View.extend({
    events: {
        'keyup ': function (e) {
            this.model.set('term', this.$el.val());
        },
        'focus ': function (e) {
            this.trigger('start');
        },
        'blur ': function (e) {
            this.trigger('stop');
        }
    }
});

var SuggestionsView = Backbone.View.extend({
    initialize: function () {
        _.bindAll(this, 'activate', 'deactivate', 'render');
        this.listenTo(this.model.matches, 'reset', this.render);
    },
    activate: function () {
        this.$el.addClass('active');
        this.render();
    },
    deactivate: function () {
        this.$el.removeClass('active');
        this.$el.html(" ");
    },
    render: function () {
        var html = '';

        if (this.model.get("term") === "") {
            html = "<p> start typing a question </p>";
        } else {
            if (this.model.matches.length === 0) {
                html = "<p> No match </p>";
            } else {
                this.model.matches.each(function(model) {
                    html += '<p>'+model.get('question')+'</p>';            
                });
            }
        }        
        this.$el.html(html);
    }
});

モデルとビューをまとめる

インスタンス化、イベントのバインド、実行

var questions = new Questions([
    {question: "what is your name"},
    {question: "How old are you"},
    {question: "what is your mothers name"},
    {question: "where do work/or study"}
]);
var controller = new QuestionController({
    questions: questions
});

var vSearch = new SearchView({
    el: '#suggestinput',
    model: controller
});
var vSuggestions=new SuggestionsView({
    el: '#suggestions',
    model: controller
});

vSuggestions.listenTo(vSearch, 'start', vSuggestions.activate);
vSuggestions.listenTo(vSearch, 'stop', vSuggestions.deactivate);

そしてhttp://jsfiddle.net/nikoshr/QSE95/で遊ぶフィドル

もちろん、すべてのインタラクションを単一のビューで処理することで、これを大幅に簡素化できますが、どこが楽しいのでしょうか?

于 2012-08-15T11:43:55.140 に答える