1

次の問題の解決策を実装する方法について、私は完全に迷っています。

バックボーン モデルのプロパティが取り込まれたバックボーン ビューがあります。このビューでは、属性が表示されます。属性の 1 つについて、ユーザーは既存の属性を追加または変更できる必要があります。これは、バックボーン モデル内のプロパティの配列に最適です (私はそう思います)。

ここのjsフィドルにテストケースを追加しました

フィドルでわかるように、ユーザーは犬favorite_snacksを追加できますが、ビューをインスタンス化するときにこれを解析してレンダリングし、それらをmysqlデータベースに正常に保存するコードを書く方法に完全に苦労しています.

これについて何か助けていただければ幸いです。私はそれを理解しようとして、週末中ずっと机に頭をぶつけていました。

4

1 に答える 1

0

後でコードを管理できるように、ビューとモデルが独立して完全に分離されて動作することを確認することをお勧めします。

したがって、この場合、各ペットは 1 つまたは複数のお気に入りのスナックを持つことができます。したがって、基本的には、単一のスナック モデルではなく、ここでスナックのコレクションを期待しています。

そのため、別の Snacks コレクションを作成してからSnack Model. 次に、別のビューを維持SnackListItemし、リストを反復処理して、SnackCollection各項目のビューをレンダリングします。

そのため、両方に個別のテンプレートを作成します

<div id="foo"></div>
<script type="text/template" id="pet-view-template">
    <p> <span><b> Dog Name: </b> </span> <%= name %> </p>
        <p> <span><b> Dog Color: </b></span> <%= color %> </p> 
    <h4> favorite snacks </h4>
    <ul class="snacks-list">
    </ul>
    snack name: <input type="text" class="snack-name" /> 
    cost : <input type="text" class="snack-cost" />    
    <button class="add-snack">add snack</button >
</script>

<script type="text/template" id="snack-view-template">
    <b>snack name:</b> <span> <%=favorite_snacks %> </span> ::
    <b>cost: </b><span> <%= favorite_snack_cost %> </span>

       <b class="toggle-change"> Change </b>
        <span class="modify-fields hide">
             <b class="modify">snack name:</b> <input type="text" class="modify-name" data-key="favorite_snacks" /> 
             <b class="modify">snack cost:</b> <input type="text" class="modify-cost" data-key="favorite_snack_cost" />    
        </span>
</script>

Snacks コレクション用に別のビューとモデルを作成しました。 これはまだ最適化できます。

Javascript

// Create a Dog Model
var Dog = Backbone.Model.extend({
    defaults: {
        name: 'New dog',
        color: 'color'
    }
});

// Create a collection of dogs
var Dogs = Backbone.Collection.extend({
    model: Dog
});

// Create  a model for Snacks
var Snack = Backbone.Model.extend({
    defaults: {
        favorite_snacks: 'bacon',
        favorite_snack_cost: '52'
    }
});

// Create a collection of Snacks
var Snacks = Backbone.Collection.extend({
    model: Snack
});

// Define the model for a Dog 
var dog = new Dog({
    name: "Spot",
    color: "white"
});

// Create a View for the Snack Item
var SnackItemView = Backbone.View.extend({
    tagName : 'li',
    className: 'snacks',
    template: _.template($('#snack-view-template').html()),
    initialize: function() {
        // Need to bind to save the context of this to the view
        _.bind('toggleChange', this);
        // Need to listen to the Model change event and render the view again 
        // as the new data has to be reflected
        this.listenTo(this.model, 'change' , this.render);
    },    
    // Assign events for the fields inside Snacks view
    events : {
        'click .toggle-change' : 'toggleChange',
        'change input'         : 'modifyData'
    },
    toggleChange: function() {
        var $change = $('.modify-fields', this.$el);
        $change.hasClass('hide') ? $change.removeClass('hide') : $change.addClass('hide');
    },
    // This will captue the data from the inputs and trigger the change event on the model
    modifyData: function(e) {
        var value = $(e.currentTarget).val(),
            key  = $(e.currentTarget).data('key');
         this.model.set(key,value);
    },
    render: function () {
        this.$el.html(this.template(this.model.toJSON()));
        return this;
    }
});

var PetView = Backbone.View.extend({
    el: '#foo',
    template: _.template($('#pet-view-template').html()),
    initialize: function () {
        this.collection = (this.collection && this.collection instanceof Backbone.Collection) || new Snacks(Snack);
    },
    events: {
        'click .add-snack' : 'addSnack'
    },
    addSnack: function () {
        // Render new snack Item
        var newSnack = new Snack({
            favorite_snacks: $('.snack-name', this.$el).val(),
            favorite_snack_cost: $('.snack-cost', this.$el).val()
        });
        this.renderSnackView(newSnack);
        // Clear the inputs
        $('input', this.$el).val('');
    },
    // render each snack view
    renderSnackView: function (snack) {
        var snackView = new SnackItemView({
            model: snack
        });
        $('.snacks-list', this.$el).append(snackView.el);
        snackView.render();
    },
    render: function () {
        var thisView = this;
        // Append the PetView
        this.$el.html(this.template(this.model.toJSON()));
        // Iterate over each snack collection of the pet and render that item
        _.each(this.collection.models, function (snack) {
            thisView.renderSnackView(snack);
        });
        return this;
    }
});



var petView = new PetView({
    model: dog
});
petView.render();

動作中のフィドルを確認する

コードの一部を説明するためにコメントを使用しました。最近バックボーンを使い始めたばかりなので、バックボーンを最初に学ぶのは大変です。しかし、慣れると非常にシンプルでありながら強力です..これが役立つことを願っています:)

ただし、アプリケーションをビルドしようとするときは、メモリ リークを減らすために、使用されていないビューとイベントを破棄する必要があります。

于 2013-05-13T21:33:05.423 に答える