追加对基于 Backbone.js 的表单没有影响

append has no effect on a form based on Backbone.js

我检索了一个基于 Backbone.js 的模板 Javascript / HTML。我需要在以下形式的字段中添加动态下拉列表:

<script type="text/template" id="compose-view-template">
<form id="email-compose" class="form-email-compose" method="get" action="">
    <div class="form-group">
        <select type="email" id="input-to" placeholder="To" class="input-transparent form-control">
        </select>
    </div>
    <div class="form-group">
        <input type="text" id="input-subject" placeholder="Subject" class="input-transparent form-control"
               value="<%= subject %>">
    </div>
    <div class="form-group">
        <textarea rows="10" class="form-control" id="wysiwyg" placeholder="Message"><%- body %></textarea>
    </div>
    <div class="clearfix">
        <div class="btn-toolbar pull-xs-right">
            <button type="reset" id="compose-discard-button" class="btn btn-gray">Annuler</button>
            <button type="submit" id="compose-send-button" onClick="fillEmailDropDown()" class="btn btn-danger">&nbsp;&nbsp;&nbsp;Envoyer&nbsp;&nbsp;&nbsp;</button>
        </div>
    </div>
</form>

</script>

Backbone部分如下:

        var ComposeView = Backbone.View.extend({


        template: _.template($('#compose-view-template').html()),

        attributes: {
            id: 'compose-view',
            class: 'compose-view'
        },

        events: {
            "click #compose-save-button, #compose-send-button, #compose-discard-button": 'backToFolders'
        },

        render: function() {
            $('#widget-email-header').html(
                '<h5>Nouvel <span class="fw-semi-bold">Email</span></h5>'
            );
            $('#folder-stats').addClass('hide');
            $('#back-btn').removeClass('hide');
            this.$el.html(this.template(this.model.toJSON()));
            this._initViewComponents();


            return this;
        },

        backToFolders: function(){
            App.showEmailsView();


        },

        _initViewComponents: function(){
            this.$("textarea").wysihtml5({
                html: true,
                customTemplates: bs3Wysihtml5Templates,
                stylesheets: []
            });

        }



    });

Javascript如下:

$(document).ready(function() {
      var listItems = '<option selected="selected" value="0">- Select -</option>';
      console.log("Preparing Auto Fill of DropDown list for email adresses");

      for (var i = 0; i < jsonData.Table.length; i++) {
        listItems += "<option value='" + jsonData.Table[i].stateid + "'>" + jsonData.Table[i].statename + "</option>";
      }
      $("#input-to").append(listItems);
});

不幸的是,.append 对 select 表单没有影响,下拉列表仍然是空的。 我也尝试使用 .html 而不是追加,但结果相同。

如果我在 select 标签中手动添加选项,它可以正常工作,但我需要动态填充它...

有什么想法吗?

听起来问题很可能是 backbone 在您尝试追加之前没有将 #input-to 元素添加到您的 html。那不会抛出任何错误,它只会默默地失败,然后 backbone 会在追加尝试后添加(空)元素。

您只知道 "safe" 在 backbone 添加了 html 之后追加您的内容,这发生在您的 render 方法中:

    render: function() {
        $('#widget-email-header').html(
            '<h5>Nouvel <span class="fw-semi-bold">Email</span></h5>'
        );
        $('#folder-stats').addClass('hide');
        $('#back-btn').removeClass('hide');
        this.$el.html(this.template(this.model.toJSON()));
        // NOW IT IS SAFE TO APPEND CONTENT...

        this._initViewComponents();


        return this;
    },

一个肯定有效的解决方案是在 render 方法中添加直接附加到元素的代码。如果附加内容是视图固有的内容,我建议这样做。

如果这看起来不连贯,那么很大程度上取决于您的 backbone 是如何设置的。在初始化视图的行之后附加内容可能是安全的:

var myView = new ComposeView({});
// NOW APPEND CONTENT

但是,只有在以下情况下才会安全:

  1. 您的视图在创建时立即呈现,并且
  2. 渲染是同步的(不首先获取外部数据或模板)。

希望这对您有所帮助,祝您好运。