Backbone和jQuery滑块

时间:2014-02-13 18:15:44

标签: javascript jquery backbone.js underscore.js

所以我一直在努力争取quire来做这件事。我正在构建一个动态表单生成器工具。其中一个功能是用户应该能够使用jQuery滑块来选择字体大小。我使用下划线模板为滑块创建div。因此,每次用户选择Label输入时,都会加载此下划线模板,并调用slider()fn对其进行初始化。这是执行此操作的代码的一部分

UnderscoreTemplate

<!-- template for plain text inpt to be shown in form generate -->
    <script type="text/template" id="text-generate-template">       
        <div class="row">       
            <div class="col-sm-10">
                <input type="text"  placeholder="Enter text here" class="label-name form-control" value="<%=model.get('label')%>">
            </div>              
            <button type="button" class="close" id="remove-element" >&times;</button>
        </div>          
        <div class="row col-sm-6"  style="margin-top:10px">
            <div id="slider-<%=model.cid%>"></div>
            <small>Font Size:  <%=model.get('fontSize')%>px </small>            
        </div>  
    </script>

因此,根据代码ablove,每个动态加载的元素都有一个带唯一ID的唯一滑块。

Backbone模型从名为“Element”

的Base元素扩展而来
    var TextElement = Element.extend({
            defaults:function(){
                return _.extend({}, Element.prototype.defaults,{
                    name: 'PlainText',
                    generateTemplateType: 'text-generate-template',
                    previewTemplateType:'text-template',
                    textAlign: 'center'     
                });
            }                               
        });

负责生成html的视图是

var ElementView = Backbone.View.extend({

            tagName: 'li',
            events : {              

                },
            initialize : function(){
                this.listenTo(this.model,'change', this.render);        
                this.render();
            },
            render : function(){                            
                var htmlContent =  $('#'+this.model.get('generateTemplateType')).html();                        
                var content = _.template( htmlContent, {elementType : elementTypes, model : this.model} );                                      
                this.$el.html( content );           
                me = this;                  
                if(this.model.get('name') == 'PlainText'){                      
                    this.$el.find('#slider-'+this.model.cid).slider({
                         min: 10,
                         max:40,
                         step: 1,
                         value:me.model.get('fontSize') > 9 ? me.model.get('fontSize') : 24,
                         change: function(event, ui) {
                            me.slide(event, ui.value);
                        }
                    }); 
                }

                return this;
            },              

            slide: function(event, index){                  
                console.log("the models id in slide function -> "+this.model.cid);
                this.model.set('fontSize', index);                  
            }
        });

所以我在这里做的是每次检测到更改时,我都会将此模型的fontSize更新为通过Slider传入的新值。

此模型所属的集合可识别此更改并自行重新呈现。

当页面上只有一个这样的元素时,一切正常。当用户添加多个元素并尝试更改每个项目的字体大小时,则只更改最后一个元素的字体大小。无论我是否滑动第一个,第二个或第三个元素,它总是将更改设置为集合中的最后一个模型,并使用不正确的字体大小值重新渲染最后一个模型。

我尝试在幻灯片功能中控制日志记录模型的ID,无论我使用哪个滑块,它总是会返回最后的模型ID。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

你有一个偶然的全局变量:

me = this;

这样做的副作用是ElementView的每个实例最终都会分享完全相同的me,而me将是您实例化的最后一个ElementView。听起来很熟悉吗?

解决方案是使用局部变量:

var me = this;

或者,如果您不需要回调中的滑块this,请使用绑定函数:

value: this.model.get('fontSize') > 9 ? this.model.get('fontSize') : 24,
change: _(function(event, ui) {
    this.slide(event, ui.value);
}).bind(this)

如果您更喜欢$.proxy以上的人,也可以使用Function.prototype.bind_.bind