骨干视图扩展?

时间:2016-12-11 09:34:23

标签: javascript jquery backbone.js underscore.js

我正在尝试创建一些从服务器获取数据的组合框。 它们都相同,但数据不同。这是我的MainView的渲染功能:

render: function () {

        ...

        this.$el.append(this.template(this.options));


        this.$('#Type').append(new App.Views.TicketTypes({ collection : new App.Models.TicketTypes() }).render().el);

        this.$('#Priority').append(new App.Views.Priorities({ collection : new App.Models.Priorities() }).render().el);

        this.$('#Status').append(new App.Views.Statuses({ collection : new App.Models.Statuses() }).render().el);

        this.$('#State').append(new App.Views.States({ collection : new App.Models.States() }).render().el);


        return this;
    }

这是主模板:

<label class="text-center">{{Type}}</label>
                    <br>
                    <div id="Type" class="form-group">

                    </div>
                    <label class="text-center">{{Priority}}</label>
                    <br>
                    <div id="Priority">

                    </div>
                    <label class="text-center">{{Status}}</label>
                    <br>
                    <div id="Status">

                    </div>
                    <label class="text-center">{{State}}</label>
                    <br>
                    <div id="State">

                    </div>
                    <br>

这是我定义的观点:

App.Views.SelectList = Backbone.View.extend({
    template: templates.SelectList,
    collection : null,
    initialize: function (options) {
        if (options) {
            this.collection = options.collection;
        }
    },
    render: function () {
        this.el.innerHTML = this.template(this.options);
        thiz = this;
        this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) {
            collection.each(function (item) {
                thiz.$('select').append("<option>" + item.get('Text') + "</option>");
                    } , this);
        }});

        return this;
    }
});

App.Views.TicketTypes = App.Views.SelectList.extend();
App.Views.Priorities = App.Views.SelectList.extend();
App.Views.Statuses = App.Views.SelectList.extend();
App.Views.States = App.Views.SelectList.extend();

这是SelectList Template:

<select class="form-control">

</select>
<br>

我的所有模特都是这样的:

{"id":1,"Text":"Netowrk"}

但这是我从服务器获得的: enter image description here

正如你所看到的只有最后一个gots数据,令人惊讶的是所有模型的所有数据都进入了最后一个。看到这里:

enter image description here

我知道如果我改变了这个渲染功能:

render: function () {
            this.el.innerHTML = this.template(this.options);
            thiz = this;
            this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) {
                collection.each(function (item) {
                    thiz.$('select').append("<option>" + item.get('Text') + "</option>");
                        } , this);
            }});

            return this;
        }

到此:

render: function () {
        this.el.innerHTML = this.template(this.options);
        this.collection.thiz = this;
        this.collection.fetch({beforeSend :App.Auth , success : function (collection , response) {
            collection.each(function (item) {
                collection.thiz.$('select').append("<option>" + item.get('Text') + "</option>");
                    } , this);
        }});

        return this;
    }

它会解决问题,但有没有更好的方法呢?

感谢。

1 个答案:

答案 0 :(得分:2)

你有一个范围问题。这样:

thiz = this;

创建一个全局thiz变量,以便迭代集合中的每个匿名函数:

collection.each(function (item) {
    thiz.$('select').append("<option>" + item.get('Text') + "</option>");
} , this);

最终使用完全相同的thiz。那些collection.each调用包含在AJAX调用(this.collection.fetch)中,JavaScript是单线程的,所以它们都是在第一个执行之前创建的。这意味着所有这些函数将使用完全相同的thiz,其值将是分配给它的最后thiz = this。这是伪装的经典封闭问题。

切换到:

this.collection.thiz = this;

您将thiz范围限定在正确的视图中,一切都按预期工作。

正确的解决方案是使用varlet正确声明thiz

var thiz = this;
// or
let thiz = this;

检查链接文档中的差异。