1

いくつかの異なる問題が発生していますが、この例は簡単に理解できると思います。このコードは、要素がデフォルトで非表示になっている HTML テンプレートを使用します (CSS を使用)。バックボーン ビューは、モデル内のデータを使用して、適切な値を表示するか、モードに値が存在しない場合は UI 要素を非表示にします。

デフォルトで (CSS を使用して) すべてが非表示になっているテンプレートがあるとします。次に例を示します。

<script type="text/template" id="Person-Template">
    <span class="fname" title="FirstName"></span>
    <span class="lname" title="LastName"></span>
    <span class="age" title="Age"></span>
</script>

各 UI 要素を非表示にするための CSS は次のとおりです。

span.fname,
span.lname,
span.age {
    display:none; 
}

したがって、私の Backbone.js モデルは次のようになります。

PersonModel = Backbone.Model.extend({
        defaults: {
            fname: undefined,
            lname: undefined,
            age: undefined
        }
    });

ビュー(簡略化)は次のようになります。

PersonView = Backbone.View.extend({
    tagName: 'div',

    initialize: function() {
        this.model.on("fname", this.updateFName, this);
        this.model.on("lname", this.updateLName, this);
        this.model.on("age", this.updateAge, this);
    },

    updateFName: function() {
        // Pseudo code 
        Get 'new' value from Model
        Obtain reference to DOM element span.fname
        Update span.fname

        if (model value is empty) {
           Hide UI element.
        }
    },

    updateLName: function() {
        // Same as above
    },

    updateAge: function() {
        // Same as above
    },

    render: function() {
        // Get model values to display
        var values = {
            FirstName : this.model.get('fname'),
            LastName : this.model.get('lname'),
            Age: this.model.get('age'),
        };

        // Load HTML template
        var template = $('#Person-Template').html();

        // Populate template with values
        var t = _.template(template, values);

       // Show / hide UI elements
       this.updateFname();
       this.updateLName();
       this.updateAge();
    }

}

最後に、質問: UI 要素を非表示または表示に設定する必要があるかどうかを判断するためだけに、render() から各 updateXYZ() メソッドを呼び出すのはハックに思えます。私のモデルには多くの属性があり、コードは少しばかげているようです。

私はSOで、何を表示すべきか、何を表示すべきかをビューが決定する責任を負うべきではないと言われました。私の質問は、では何が責任を負っているのかということです。ユーザーは、名をクリアする(有効な)アクションを実行する場合があります。その場合、ビューに「名:」の後に値が表示されないようにします。

4

1 に答える 1

3

まず第一に、values手動でビルドする必要はありませんtoJSON:

var values = this.model.toJSON();

次に、記入済みのテンプレートをビューの に追加する必要がありますel

this.$el.html(_.template(template, values));

テンプレートには、おそらくテンプレートに表示するものを含める必要があります。

<script type="text/template" id="Person-Template">
    <span class="fname" title="FirstName">F: <%= fname %></span>
    <span class="lname" title="LastName">L: <%= lname %></span>
    <span class="age" title="Age">A: <%= age %></span>
</script>

3 つの部分ごとに関数を分離する必要はありませんrender

_(values).each(function(v, k) {
    var m = _(v).isUndefined() ? 'hide' : 'show';
    this.$('.' + k)[m]();
}, this);

イベントに戻ります。"fname"カスタム イベントを追加しない限り、イベントなどありません。しかし、その必要はありません。モデルが変更されると、モデルがトリガーされ"change""change:fname"イベントが発生します。ただしfname、気にする必要があるのは次のとおりです。"change"

initialize: function() {
    _.bindAll(this, 'render');
    this.model.on("change", this.render);
},

の 3 番目の引数について心配する必要がないように、 をrender使用してビュー インスタンスにもバインドしました。_.bindAllthis.model.on

これで動作するものがあります: http://jsfiddle.net/ambiguous/46puP/


「これを表示する必要がある」ロジックをテンプレートにプッシュすることもできます。

<script type="text/template" id="Person-Template">
    <% if(fname) { %><span class="fname" title="FirstName">F: <%= fname %></span><% } %>
    <% if(lname) { %><span class="lname" title="LastName">L: <%= lname %></span><%  } %>
    <% if(age)   { %><span class="age" title="Age">A: <%= age %></span><%           } %>
</script>

そしてあなたを簡素化しますrender

render: function() {
    var values   = this.model.toJSON();
    var template = $('#Person-Template').html();
    this.$el.html(_.template(template, values));
    return this;
}

デモ: http://jsfiddle.net/ambiguous/W9cnJ/

このアプローチはおそらく最も一般的であり、何も問題はありません。前の回答が伝えようとしていたことを誤解していると思います。テンプレートは、どの情報を表示するかを既に選択しているため、表示を試みる前に、たとえば が設定されている<%= ... %>かどうかを確認してはならないという正当な理由はありません。fnameデータの性質によってはif(!_(fname).isUndefined())、テンプレートでなどを使用したい場合がありますが、単純な真実性チェックで十分です。ただし、age場合によってはこれが問題になる可能性があるため、もう少し厳密にしたい場合があります。

于 2012-06-30T17:33:48.273 に答える