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我用's方法抓取它并$.ajax在我的视图中为我的 Backbone 应用程序管理它:

<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"
    }
]

有了这些数据products,由于parseResults在视图中,我将 ajax 放入集合中,因此我不再拥有该对象。

如何解析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

也看起来服务器没有给你你需要的答案,所以 Backbone 有自己的解析: http ://backbonejs.org/#Collection-parse

我也是逻辑少模板的粉丝。所以通过集合的迭代必须在视图中而不是在模板中。也请检查这个(特别是第二点): http: //ozkatz.github.io/avoiding-common-backbonejs-pitfalls.html

以正确的方式使用集合,然后在视图中渲染它,您可以监听 add 或 reset 事件并以这种方式填充集合。this.collection.on('add', this.render); //通过模型获取模型 this.collection.on('reset', this.render); //获取所有模型(需要在 fetch 调用中指定一个参数 {reset : true}

于 2013-04-17T03:08:27.357 回答