javascript - 错误: cannot call methods on tabs prior to initialization; attempted to call method 'destroy'

标签 javascript jquery twitter-bootstrap jquery-ui backbone.js

我正在努力将旧网站更新为新版本的 jQuery 并应用 Bootstrap 。

我们正在使用

 backbone.js
 jQueryui and
 bootstrap.js.

我收到以下错误:错误:无法在初始化之前调用选项卡上的方法;尝试调用方法“destroy”

与之相关的代码行是:

谢谢

define([
  'jquery',
  'jqueryui',
  'underscore',
  'backbone',
  'vm',
  'events',
  'models/product',
  'text!templates/editor/page.html'
], function ($, jui, _, Backbone, Vm, Events, Product, PageTemplate) {
    var EditorPage = Backbone.View.extend({

        model: Product,

        el: '#editor',

        _$editorErrorContainer: undefined,

        events: {
          "click #toolbar": "onToolbarClicked"
        },

        initialize: function () {
            this.bindSaveEvents();
            Events.unbind("addText");//HACK: Prevents zombie listeners for this specific situation
            Events.bind("addText", this.onAddText, this);
        },

        onAddText: function (e) {
            var layers = this.model.get('layers');
            var textCollections = [];

            //Search for valid text collections in our layer and push into our array
            layers.models.forEach(function (layer) { 
                var tc = layer.get("textCollection");
                if (typeof tc !== "undefined") {
                    if (layer.get("allowText")) {
                        var printColor = layer.get("printColor");
                        var src;
                        if(printColor) { src = printColor.get("src"); }
                        var _tc = { 'textCollection': tc, 'src': src, 'name':layer.get('name'), 'cid': layer.cid };
                        textCollections.push(_tc); 
                    }
                } 
            });

            //if there's no choice to make, just add the text element.
            if (textCollections.length == 1) {
                var textCollection = textCollections[0].textCollection;
                AddTextToCollection(textCollection);
                return;
            }

            //Otherwise create dialog for choosing in which text collection to put a new text object
            var dialogHTML = "<div> <p>What color would you like this text?</p>";
            //Generate selections, use the src attribute of the print color if it uses printcolor
            //TODO use other attributes of a textCollection such as rgb color if it uses it etc
            textCollections.forEach(function (textCollection, i) {
                var imgurl = "";
                if(textCollection.src) {
                    imgurl = "/productEditor/assets/printcolors/icons/" + textCollection.src;
                }
                //Customers wont like zero indexed option names
                var id = i + 1;
                dialogHTML += "<p data-id= " + i + " class='selection'> Group " + id + ": " + textCollection.name + "<img src='" + imgurl + "'/> </p>";
            });
                dialogHTML += "</div>"

            $(dialogHTML).dialog({    
                            modal: true,
                            width: "25%",
                            height: "auto",
                            dialogClass: "textAddDialog",
                            resizable: false,
                            position: {
                                my: 'left top',
                                at: 'left top',
                                of: $("#editor"),
                                collision: 'flip'
                            },
                            show: 'fade', 

                            create: function() {
                                var that = this;
                                //bind dialog events
                                $(this).children(".selection").click(function(){
                                    $(that).children('.selected').removeClass("selected");
                                    $(this).addClass("selected");
                                });
                            },

                            open: function (event, ui) {
                                $('.ui-dialog').css('z-index',2003);
                                $('.ui-widget-overlay').css({
                                    'z-index': 2002, 
                                    'opacity': 0.5                                
                                });
                            },

                            close: function() {
                                $(this).children(".selection").unbind();
                                $(this).dialog('destroy').remove();
                            },

                            buttons: [{
                                text: "Accept",
                                "class": "acceptButton",
                                click: function() {
                                    var index = $(this).children('.selected').data('id');

                                    if(index >= 0) {
                                        var textCollection = textCollections[index].textCollection;
                                        AddTextToCollection(textCollection);
                                    }

                                    $(this).dialog("close");
                                }
                            },
                            {
                                text: "Cancel",
                                click: function() {
                                    $(this).dialog("close");
                                }
                            }
                            ]

                        });

            function AddTextToCollection (textCollection) {
                //Create text element in chosen group
                var entry = textCollection.createEntry();
                //Show user that this is a fresh text element that needs changing
                entry.set("text", "Edit Me!");
                entry.set("freshElement", true);//Fresh element denotes a completely new element, used to delete this element if user adds an element -> cancel button
                //Trigger mouseup on element so our text editor dialog will pop for this element
                var elem = $('.text_modifier[data-cid="' + entry.cid + '"]');
                elem.trigger("click");
            }
        },

        bindSaveEvents: function(){
            Events.on('saveError', this.onSaveError.bind(this));
            Events.on('saveSuccess', this.onSaveSuccess.bind(this));
        },

        unbindSaveEvents: function(){
            Events.off('saveError', this.onSaveError.bind(this));
            Events.off('saveSuccess', this.onSaveSuccess.bind(this));
        },

        onToolbarClicked: function (e) {
            //console.log("toolbar clicked");
            //this._productView.clearSelectedChildren();
        },

        onSaveError: function(errorMessage){
//            if(this._$editorErrorContainer === undefined){
//                this._$editorErrorContainer = $("<div/>").addClass("error");
//                $(this.el).before(this._$editorErrorContainer);
//            }
//            this._$editorErrorContainer.text(errorMessage).show();
            $('#appError').text(errorMessage).show();
        },

        onSaveSuccess: function(){
//           if(this._$editorErrorContainer != null){
//               this._$editorErrorContainer.hide();
//           }
           $('#appError').hide();
        },

        onRenderComplete: function (e) {
            // ADD THE RETURN ELEMENT TO THE LIST OF 
            this._loadList = _.without(this._loadList, e);
            if (this._loadList.length == 0) {
                $(this.el).removeClass('loading');
            }
        },

        remove: function(){
            this.unbindSaveEvents();
        },

        renderApp: function () {
            var that = this;

            // PUT LIST OF ITEMS THAT RENDER INTO ARRAY
            // renderComplete WILL REMOVE ITEMS, AND CHANGE STATE TO VISIBLE WHEN ALL ARE LOADED
            this._loadList = ['layer', 'product', 'modifiers', 'tabs']

            // CREATE PREVIEW MODIFIERS
            require(['views/modifiers/product'], function (PreviewModifierView) {
                that._modifierView = new PreviewModifierView({ model: that.model });
                that._modifierView.on("renderComplete", that.onRenderComplete, that);
                that._modifierView.render();
            });

            // CREATE PREVIEW
            require(['views/preview/product'], function (PreviewProductView) {
                that._productView = new PreviewProductView({ model: that.model });
                that._productView.on("renderComplete", that.onRenderComplete, that);
                that._productView.render();
            });

            // CREATE PRODUCT NAME DISPLAY
            require(['views/toolbar/productname'], function (ProductNameView) {
                that._productNameView = new ProductNameView({ model: that.model });
                that._productNameView.render();
            });

            // CREATE PRODUCT DESCRIPTION DISPLAY
            require(['views/toolbar/productdescription'], function (ProductDescView) {
                that._productDescriptionView = new ProductDescView({ model: that.model });
                that._productDescriptionView.render();
            });

            // CREATE TOOLBAR
            require(['views/toolbar/layer'], function (ToolbarLayerView) {
                that._toolbarView = new ToolbarLayerView({ model: that.model });
                that._toolbarView.on("renderComplete", that.onRenderComplete, that);
                that._toolbarView.render();
            });

            // CREATE FINISHED BUTTON
            require(['views/toolbar/finished'], function (FinishedView) {
                that._finishedView = new FinishedView({ model: that.model });
                that._finishedView.render();
            });

            // CREATE TABS
            require(['views/tabs/product'], function (TabsView) {
                that._tabsView = new TabsView({ model: that.model });
                that._tabsView.on("renderComplete", that.onRenderComplete, that);
                that._tabsView.render();
            });

        },

        render: function () {
            //console.log("editor render!");
            //console.log(this.model);
            //$('#productName').html(this.model.get);
            var pageTemplate = _.template(PageTemplate, this);
            $(this.el).html(pageTemplate);
            $('#button-editor-help').show(); // GET'S HIDDEN ON THE APPROVAL PAGE

            this.renderApp();
        }

    });

    return EditorPage;
});

最佳答案

  1. 在选项卡 View 中,连接一个调试器,在其中调用 destroycreate
  2. 复制该错误并检查您是否在初始化之前调用 destroy

关于javascript - 错误: cannot call methods on tabs prior to initialization; attempted to call method 'destroy' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37444695/

相关文章:

javascript - 将数据传递给模态( Bootstrap )

html - 如何使用 Handlebars 为 Meteor.js 中的每个命令填充 Bootstrap 网格系统?

html - Bootstrap 列在不应该调整大小为单行时

javascript - 如何使用 CSS 固定宽度和自动调整大小来设置 div 样式?

javascript - 如何 "join"2个 Angular 网络请求

javascript - Mobile Safari 的 jQuery 动画性能

php - 如何获取在其他页面上选择的值?

将 div 转换为 ul 并将 div 内容转换为 li 后,jquery 缺少行

javascript - 如何调用bootstrap datepicker的javascript函数?

javascript - 如何使用 PDFJS 突出显示文本?