牵线木偶ItemView子视图,未触发事件

时间:2015-03-12 12:04:20

标签: backbone.js marionette

所以这是ParentView上的代码: 相关方法:

openChildView: function(){

    var childView = new ChildView({
            container: $container //container where the child map should be appended
    });

    childView.show();
}

这是ChildView的代码:

    ChildView = Marionette.ItemView.extend({

        template: _.template($(templates_c).filter('#my_child_view_template').html()),

        ui: {
            saveButton: 'button.js-save',
            uploadButton: 'button.js-upload',
            deleteButton: 'button.js-discard'
        },
        events: {
            'click @ui.saveButton': function() {
                log.debug('save');
            },
            'click @ui.uploadButton': function() {
                log.debug('upload');
            },
            'click @ui.deleteButton': function() {
                log.debug('delete');
            }
        },
        show: function() {
            this.render();
        },

        initialize: function(){
            this.container = this.options.container;
            this.id = this.options.id;
        },

        remove: function(){
            // Don't know yet if this is the proper way, but for now it works
            this.container.find('.container-child-view').remove();
        },

        render: function(){
            this.container.append(this.template({
                id: this.id,
                img: '...'
            }));

            log.debug('on render');
            this.bindUIElements();
            this.delegateEvents();

            return this;
        }
    });

这是ChildView模板的代码:

<script type="text/x-template" id="my_child_view_template">
    <div class="block container-child-view">
        <div class="block-title">
            <h4><%= id %></h4>
        </div>

        <div class="img">
            <img src="<%= imgUrl %>">
        </div>
        <div class="row text-center">
            <div class="btn-group btn-group-xs">
                <button id="discard" type="button" class="js-discard btn btn-alt btn-warning"><i class="fa fa-times-circle"></i> Cancel</button>
                <button id="upload" type="button" class="js-upload btn btn-alt btn-primary"><i class="fa fa-upload"></i> Upload</button>
                <button id="save" type="button" class="js-save btn btn-alt btn-primary"><i class="fa fa-save"></i> Save</button>
            </div>
        </div>
    </div>
</script>

childView正在父视图上呈现,但没有触发任何事件(保存,丢弃,上传)。

任何提示/想法?

感谢。

1 个答案:

答案 0 :(得分:1)

.delegateEvents()绑定事件的方式是委托给视图el。在source中,您会看到:

delegate: function(eventName, selector, listener) {
  this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
},

正如您所看到的,在视图.on()上调用了jQuery $el。如果将selector参数传递给.delegate()(比如说​​.js-save),则将选择器的事件委托给其包含的视图el。< / p>

您覆盖.render()的方式,您选择替换&#34; all-mighty&#34; this.el this.container。调用this.delegateElements()仍然会调用.delegate()来对this.el进行绑定,而您的视图实际上位于this.container。视图事件正在冒泡到未绑定的容器。

快速修复可能会覆盖渲染,如下所示:

    render: function(){
        this.container.append(this.template({
            id: this.id,
            img: '...'
        }));

        log.debug('on render');
        this.bindUIElements();

        // .setElement is an internal method that will
        // make your container the view's el and will call
        // .delegateEvents on this new el
        this.setElement();

        return this;
    }
});

除非我还为您提供了更加面向框架的解决方案,否则我可能无法称自己为正直的Marionette社区居民。在我看来,您已覆盖.render因为您希望 1。ItemView渲染为特定的包含元素且 2。您希望将非模型数据加载到模板中。

1。设置视图el

Backbone将为视图的el采用现有的DOM元素。只需在视图的实例化中传入选择器或jQuery对象,

var childView = new ChildView({ el: $container });

Marionette .render()方法会将视图附加到$container

2。将非模型数据传递到模板

Marionette拥有这个方便的视图实用程序templateHelpers,可让您将数据放在模板渲染器的范围内。数据可以是任何JS对象,包括函数。只需在您的视图中包含该属性即可。

templateHelpers: function () {
    return {
      img: function(){
        return 'http://some-domain.com/img/" + this.id;
      },

      id: this.id
    };
  }
});

其中,templateHelper this的此版本是视图的上下文。