3

によって作成されたBackbone collections相対内でそれらを操作し、それらをプルする方法を理解しようとしています。template enginesub view

これは私のアプリで試したロジックです:

ここに画像の説明を入力

ajax requestは私にこのオブジェクトを返します:

{
    "products":[
        {
            "id":"43",
            "text":"Sunset Chips",
            "image":"43.png"
        },{
            "id":"107",
            "text":"Pringles Hot & Spicy",
            "image":"107.png"
        }
    ],
    "brands":[
        {
            "id":"132",
            "text":"P&G",
            "image":"132.png"
        },{
            "id":"27",
            "text":"Kinder",
            "image":"27.png"
        }
    ]
}

jQueryのメソッドでそれを取得し、$.ajaxここで私のビューでバックボーン アプリ用に管理します。

<script type="text/javascript">

var search = {};

search.app = {};
search.app.id = "#search-results";

search.product = {};
search.product.defaults = {
    id:0,
    text:"<?php echo __('No results here');?>",
    image:"<?php echo $this->webroot;?>files/product/default.png",
};

$(function(){

    var SearchApp = new Search.Views.App({
        id:"#search-results"
    });

    var ProductList = new Search.Collections.Products();
    var subView;

    function parseResults (response, search) {

        for (var i = response.products.length - 1; i >= 0; i--) {
            ProductList.add([new Search.Models.Product(response.products[i])]);
        };

        subView = new Search.Views.Product ({
            collection:ProductList,
            id:"#product-results",
            template:"#results-product-template" // solo in this.options.template
        });

        updateResults();
    }

    function updateResults () {
        console.log('updateResults: Ritorno il risultato quando hunter riceve una risposta dal server');
        if ($('#search-results').length == 0) {
            $('div.main > section:first-child').before('<section id="search-results"></section>');
        }
        SearchApp.renderProductCollection(subView);
    }

    $('#search-results .close').on('click', function () {
        $('#search-results').animate({height:0}, 500, function () {
            $(this).remove();   
        })
    });

    var callbacks = {
        on_response:parseResults // function presente in backbone.search.js
    };

    $('#hunter').hunter({url:'<?php echo $this->request->base; ?>/searches/default_search', callback:callbacks, ajax_params:{limit:10, term:'%%'}});

});
</script>

これは私のバックボーン アプリケーションです。

var Search = {
    Models: {},
    Collections: {},
    Views: {},
    Templates:{}
}

Search.Models.Product = Backbone.Model.extend({
    defaults: search.product.defaults || {},
    initialize:function () {
        console.log("initialize Search.Models.Product");
        this.on("change", function (){
            console.log("chiamato evento change del Model Search.Models.Product");
        });
        this.on("change:text", function () {
            console.log("chiamato evento change:text del Model Search.Models.Product");
        });
    }
});

Search.Collections.Products = Backbone.Collection.extend({
    model: Search.Models.Product,
    initialize:function () {
        console.log("initialize Search.Collections.Products");
        console.log(this);
        console.log(this.length);
        console.log(this.models);
    }
});

Search.Views.App = Backbone.View.extend({
    initialize:function () {
        console.log("initialize Search.Views.App");
        this.$prd = this.$('#product-results');
    },
    render:function () {

        console.log("render Search.Views.App");
    },
    renderProductCollection:function (subView) {
        console.log("Search.Views.App > renderProductCollection");
        console.log('subView.getTemplate() => ' + subView.getTemplate());
        $(this.id).html(subView.getTemplate());
    }
});

Search.Views.Product = Backbone.View.extend({
    initialize:function () {
        console.log("initialize Search.Views.Product");
    },
    getTemplate:function (data) {
        if (data == null || data == undefined) {
            data = this.collection.toJSON() || this.model.toJSON(); 
        }
        var template = Handlebars.compile($(this.options.template).html());
        console.log(data);
        return '<ul id="product-results" class="w-1-4">' + template(data) + '</ul>';
    },
    render:function () {
        console.log("render Search.Views.Product");
        return this;
    }
});

テンプレートは次のHandlesbarとおりです。

<ul class="w-1-4">
    <li>
        <b>Products</b>
    </li>
   {{#each products}}
    <li>
        <a href="{{url}}">
            <div class="origin {{type}}" title="{{name}}"><img src="'.$this->webroot.'img/icons/16/origin/{{icon}}"></div>
        </a>
        <div>
            <a href="{{url}}" class="font-default-bold {{model}}-btn">{{name}}</a>
            {{#support}}<a href="{{support.url}}" class="font-small">{{support.name}}</a>{{/support}}
        </div>
    </li>
    {{/each}}
</ul>

私の問題は、Handlesbarテンプレート内のデータを解析しようとするときです。 内のデータを解析したためsub view collection、次のArrayような構造になっています。

[
    {
        "id":"43",
        "text":"Sunset Chips",
        "image":"43.png"
    },{
        "id":"107",
        "text":"Pringles Hot & Spicy",
        "image":"107.png"
    }
]

このデータでは、コレクション内に ajax を配置したビューにproductsオブジェクトがありません。parseResults

products小道具名なしで配列を解析するにはどうすればよいですproductsか、またはデータを正しい方法で保持するにはどうすればよいですか?

私は自分のアプリで問題を解決するために次のようなことができることを知っています:

var container = new array();
container['products'] = this.collection.toJSON();
data = container;

var template = Handlebars.compile($(this.options.template).html());
return '<ul id="product-results" class="w-1-4">' + template(data) + '</ul>';

しかし、これは正しい方法ですか、それとも何か不足していますか?

4

1 に答える 1

0

Backbone を使用している場合は、$.ajax を使用する必要はありません。

collection.fetch http://backbonejs.org/#Collection-fetchを使用します

また、サーバーが必要に応じて回答を提供していないように見えるため、バックボーンには独自の解析があります: http://backbonejs.org/#Collection-parse

また、私はロジックレステンプレートのファンです。したがって、コレクションの反復は、テンプレートではなくビューにある必要があります。また、これを確認してください(特にポイント2): http://ozkatz.github.io/avoiding-common-backbonejs-pitfalls.html

コレクションを正しい方法で使用してレンダリングすると、ビューで add または reset イベントをリッスンし、その方法でコレクションにデータを入力できます。this.collection.on('add', this.render); // モデルごとにモデルを取得 this.collection.on('reset', this.render); // すべてのモデルを取得します (フェッチ呼び出しでパラメーター {reset : true} を指定する必要があります)

于 2013-04-17T03:08:27.357 に答える