ItemView事件不触发

时间:2013-03-12 11:29:39

标签: backbone.js marionette

我想做什么:

在里面呈现带有选项标签的选择下拉列表,当用户在下拉列表中选择一个选项时,获取新选择的模型并使用它做任务。

问题:

我很难在通过CompositeView调用的ItemView中触发更改事件。

出于某种原因,CompositeView:change(log:holy moses)正在被触发,但它对我没什么帮助,因为它不会给我选择的模型。

我尝试了很多东西,但没有真正奏效。

任何帮助将不胜感激!

Configurator.module('Views.Ringsizes', function(Views, Configurator, Backbone, Marionette, $, _) {

    Views.DropdownItem = Marionette.ItemView.extend({
        tagName: 'option',
        template: "#dropdown-item",


        modelEvents: {
            'change': 'modelChanged'
        },

        onRender: function(){
            console.log('tnt');
            this.$el = this.$el.children();
            this.setElement(this.$el);                
        },

        modelChanged: function(model) {

            console.log("holy mary");

        }            
    });

    Views.DropdownView = Marionette.CompositeView.extend({
        template: "#dropdown-collection",
        className: 'configurator-ringsizes-chooser',
        itemView: Views.DropdownItem,
        itemViewContainer: '.product_detail_ring_sizes',

        events: {
            "change": "modelChanged"
        },
        initialEvents: function(){},
        initialize: function(){
            console.log(this.model);
            this.collection = new Backbone.Collection(this.model.getRingsizes());

        },
        modelChanged: function(model) {
            console.log("holy moses");
        }

    });

    Views.List = Marionette.CollectionView.extend({
        className: 'configurator-ringsizes',
        itemView: Views.DropdownView
    });
});

模板代码:(如果需要)

<script type="text/template" id="dropdown-item">
  <option value="<@- code @>" <@ if(current) { @> selected="selected" <@}@> ><@- name @>    </option>
</script>

<script type="text/template" id="dropdown-collection">
   <div class="accordionContent accordionContent_ringsizes">
     <div class="configurator-ringsizes-chooser-ringsizes-region">
        <select class="product_detail_ring_sizes"></select>
     </div>
   </div>
</script>

2 个答案:

答案 0 :(得分:0)

当您选择它时,“更改”事件不会在选项上触发,而是在您更改选择选项时触发选择(这就是它在复合视图上触发的原因)。

所以你应该在itemView中使用它:

events: {
    'click' : 'modelChanged'
}

答案 1 :(得分:0)

好的,我终于开始工作了。

我有点失望,我必须依赖于数据属性, 但这是我找到的唯一方法。我已经花了很长时间了:))

以下是我现在的表现:

模板代码:

<script type="text/template" id="dropdown-item">
  <option data-cid="<@- cid @>" value="<@- code @>" <@ if(current) { @> selected="selected" <@}@> ><@- name @></option>
</script>

<script type="text/template" id="dropdown-collection">
    <div class="configurator-ringsizes-chooser-ringsizes-region">
      <select class="product_detail_ring_sizes"></select>
    </div>
</script>

代码:

Configurator.module('Views.Ringsizes', function(Views, Configurator, Backbone, Marionette, $, _) {

    Views.DropdownItem = Marionette.ItemView.extend({
        tagName: 'option',
        template: "#dropdown-item",

        serializeData: function() {

            var data = {
                cid: this.model.cid,
                code: this.model.get('code'),
                name: this.model.get('name'),
                current: this.model.get('current')
            };

            return data;
        },            
        onRender: function(){
            this.$el = this.$el.children();
            this.setElement(this.$el);                
        }        
    });

    Views.DropdownView = Marionette.CompositeView.extend({
        template: "#dropdown-collection",
        className: 'configurator-ringsizes-chooser',
        itemView: Views.DropdownItem,
        itemViewContainer: '.product_detail_ring_sizes',

        events: {
            "change select": "modelChanged"
        },

        initialEvents: function(){},

        initialize: function(){
            this.collection = new Backbone.Collection(this.model.getRingsizes());
        },

        modelChanged: function(e) {

            var cid = $(e.currentTarget+"option:selected").data('cid');

            var currentModel = this.collection.find(function(elem) {
                return elem.get('current');
            });

            var model = this.collection.find(function(elem) {
                return elem.cid === cid;
            });

            currentModel.set({
                current: false
            });

            model.set({
                current: true
            });

            // AND here i'm doing my stuff, getting the overall model through this.model, the collection of options through this.collection and the currently selected model through currentModel.
        }         

    });

    Views.List = Marionette.CollectionView.extend({
        className: 'configurator-ringsizes',
        itemView: Views.DropdownView,
        model: this.model
    });
});