Dojo domConstruct.create不会在postCreate

时间:2015-08-18 09:51:04

标签: dojo widget episerver

我是Dojo的新手,我正在制作我的第一个小工具,用于EPiServer CMS。 小部件应该在单击按钮时动态添加联系人。这意味着我的templateString唯一的控件是一个按钮。点击它时,我调用一个函数,创建所有其他控件,包含联系信息,如名称,电子邮件等。这工作正常,我使用domConstruct.create没有问题。

事情是,当我想根据来自服务器的值创建现有联系人时,我无法设法使用domConstruct.create,它只返回" undefined"。我在postCreate事件中进行调用,该事件发生在DOM准备好之后。 (我也对此进行了测试)。有没有人知道什么可能是错的?就像我说的,当点击Add按钮时创建控件就像魅力一样。

抛出错误的函数是:

postCreate: function () {
            // call base implementation
            this.inherited(arguments);

            //this._loadContacts(this.value);
            var node = domConstruct.create("fieldset", { id: "test" }, "cccp"); //this simple create instruction returns undefined here. 

            //Bind button
            this.connect(this.btnAdd, "onclick", dojo.partial(this._createContact, new Object()));

        },

正好在执行domConstruct.create的行上。以下是小部件的完整代码:

define([
    "dojo/_base/array",
    "dojo/_base/connect",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/dom-construct",
    "dojo/on",


    "dijit/_CssStateMixin",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",

    "epi/epi",
    "epi/shell/widget/_ValueRequiredMixin"
],
function (
    array,
    connect,
    declare,
    lang,
    domConstruct,
    on,

    _CssStateMixin,
    _Widget,
    _TemplatedMixin,
    _WidgetsInTemplateMixin,

    epi,
    _ValueRequiredMixin
) {
    var amountContacts = 0;
    var contactContainerPrefixName = "contactInfo";

    return declare("meridian.editors.StringList", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin], {

        templateString: "<div class=\"dijitInline\">\
                            <form id=\"cccp\" action=\"\">\
                            </form>\
                            <button id=\"btnAdd\" data-dojo-attach-point=\"btnAdd\" type=\"button\" class=\"\">Add Contact</button><br/> \
                            <span>${helptext}</span>\
                        </div>",

        baseClass: "epiStringList",

        helptext: "Place items on separate lines",

        intermediateChanges: false,

        value: null,

        multiple: true,

        onChange: function (value) { },

        _onChange: function (value) {
            this.onChange(value);
        },

        postCreate: function () {
            // call base implementation
            this.inherited(arguments);

            //this._loadContacts(this.value);
            var node = domConstruct.create("fieldset", { id: "test" }, "cccp"); //this simple create instruction returns undefined here. 

            //Bind button
            this.connect(this.btnAdd, "onclick", dojo.partial(this._createContact, new Object()));

        },

        isValid: function () {
            // summary:
            //    Check if widget's value is valid.
            // tags:
            //    protected, override

            return !this.required || lang.isArray(this.value) && this.value.length > 0 && this.value.join() != "";
        },


        _loadContacts:function(data)
        {
            for (var i = 0; i < data.length; i++) {
                this._createContact(data[i]);
            }
        },


        _createContact:function(data)
        {
            //increase the number of contacts
            amountContacts++;
            var contactInfoContainer = contactContainerPrefixName+amountContacts;

            //Create container for contact data
            var contactInfo = domConstruct.create("fieldset", { id: contactInfoContainer }, "cccp");

            //Create container for PROPERTIES
            var contactInfoProperties = domConstruct.create("div",  {class: "properties"}, contactInfoContainer);

            //Name
            this._createTextbox("name", data.fullName, "Name", contactInfoProperties, false, false);

            /*//Email
            this._createTextbox("email", "Email", contactInfoProperties, false);

            //Phone 1
            this._createTextbox("phoneOne", "Phone 1", contactInfoProperties, true);

            //Phone 2
            this._createTextbox("phoneTwo", "Phone 2", contactInfoProperties, true);

            //Fax
            this._createTextbox("fax", "Fax", contactInfoProperties, false);

            //Organization
            this._createTextbox("organization", "Organization", contactInfoProperties, false);

            //Department
            this._createTextbox("department", "Department/Unit", contactInfoProperties, false);

            //Role
            this._createTextbox("role", "Role/Job title", contactInfoProperties, false);*/

            //Website
            this._createTextbox("website", data.website, "Website", contactInfoProperties, false, false);

            //Address
            //this._createTextbox("address", "Address", contactInfoProperties, false);

            //TLP
            this._createTLP_DDL("tlp", "TLP", contactInfoProperties);


            //Create container for CATEGORIES
            var contactInfoCategories = domConstruct.create("div", { class: "categories" }, contactInfoContainer);

            //Categories heading
            var p=domConstruct.create("p", { class: "heading" }, contactInfoCategories);
            p.innerHTML = "Categories";

            //Alert, Warning & Incident Response
            this._createCategory("alert", contactInfoCategories, "Alert, Warning & Incident Response");

            //Threat
            this._createCategory("threat", contactInfoCategories, "Threat");

            //Vulnerability
            this._createCategory("vulnerability", contactInfoCategories, "Vulnerability");

            //Industry
            this._createCategory("industry", contactInfoCategories, "Industry");

            //Policy
            this._createCategory("policy", contactInfoCategories, "Policy");

            //R & D
            this._createCategory("rd", contactInfoCategories, "R & D");

            //Sharing
            this._createCategory("sharing", contactInfoCategories, "Sharing");

            //Crime
            this._createCategory("crime", contactInfoCategories, "Crime");

            //SCADA/Process Control
            this._createCategory("scada", contactInfoCategories, "SCADA/Process Control");

            //Assurance
            this._createCategory("assurance", contactInfoCategories, "Assurance");

            //Standards
            this._createCategory("standards", contactInfoCategories, "Standards");

            //Resilience
            this._createCategory("resilience", contactInfoCategories, "Resilience");

            //Exercises
            this._createCategory("exercises", contactInfoCategories, "Exercises");

            //Defence
            this._createCategory("defence", contactInfoCategories, "Defence");

            //Media handling
            this._createCategory("media", contactInfoCategories, "Media handling");

            //General PoC
            this._createCategory("poc", contactInfoCategories, "General PoC");



            //Add remove button
            var btnRemove = domConstruct.create("input", { type: "button", id: "btnRemove" + amountContacts, value: "Remove"/*,onclick:"_deleteContact(this)"*/ }, contactInfo);
            this.connect(btnRemove, "onclick", dojo.partial(this._deleteContact, btnRemove.id));

        },

        _createTextbox:function(id, textBoxValue, labelText, parent, checkbox, checkboxChecked)
        {
            var currentId = id+amountContacts;

            var textboxContainer = domConstruct.create("div",  {class:"form-item"}, parent);

            this._createLabel(currentId, textboxContainer, labelText);

            //Create textbox and attach update handler
            var textbox = domConstruct.create("input", { type: "text", id: currentId, name: currentId }, textboxContainer);
            if (textBoxValue)
                textbox.value = textBoxValue;

            this.connect(textbox, "onchange", this._updateValue);

            if (checkbox) {
                this._createCheckbox("inline", textboxContainer, currentId + "_24", "24/7?");
            }
        },


        _createTLP_DDL:function(id, labelText, parent)
        {
            var currentId = id+amountContacts;

            var ddlContainer = domConstruct.create("div", { class: "form-item" }, parent);
            this._createLabel(currentId, ddlContainer, labelText);

            var ddl = domConstruct.create("select", { name: currentId, id: currentId }, ddlContainer);

            //Add options
            var option1 = domConstruct.create("option", { val: "-1" }, ddl);
            option1.innerHTML = "None";

            var option1 = domConstruct.create("option", { val: "1" }, ddl);
            option1.innerHTML = "Yes";

            var option1 = domConstruct.create("option", { val: "0" }, ddl);
            option1.innerHTML = "No";
        },

        _createCategory:function(id, parent, checkboxText)
        {
            var currentId = id + amountContacts;


            var categoryContainer = domConstruct.create("div", { class: "form-item inline" }, parent);
            this._createCheckbox("", categoryContainer, currentId, checkboxText);
        },

        _createLabel:function(forId, container, labelText)
        {
            var label = domConstruct.create("label", { for: forId }, container);
            label.innerHTML = labelText;
        },

        _createCheckbox:function(labelClass, container, checkboxId, checkboxText){
            var labelCheckbox = domConstruct.create("label", { class: labelClass }, container);

            //Create checkbox and attach update handler
            var checkbox = domConstruct.create("input", { type: "checkbox", id: checkboxId, name: checkboxId }, labelCheckbox);
            this.connect(checkbox, "onchange", this._updateValue);

            var span = domConstruct.create("span", {}, labelCheckbox);
            span.innerHTML = checkboxText;
        },

        _deleteContact:function(targetBtnId)
        {
            var userInput = window.confirm("Are you sure you want to delete this contact?");
            if (userInput) {
                dojo.destroy(contactContainerPrefixName+targetBtnId[targetBtnId.length-1]);
            }
        },

        _updateValue: function () {
            //TODO: Delete test data
            var contacts = [];

            //The amount of contacts can have changed after deletions, so the global variables might not hold the real value
            var actualAmountContacts = 0;

            for (var i = 1; i <= amountContacts; i++) {
                if (this._isValidContact(i)) {

                    var currentContact = new Object();
                    currentContact.fullName = this._getValueById("name" + i);
                    currentContact.website = this._getValueById("website" + i);

                    contacts[actualAmountContacts] = currentContact;
                    actualAmountContacts++;
                }
            }



            this._set("value", contacts);
            this.onChange(contacts);
        },

        _getValueById: function (id) {
            var node = dojo.byId(id);
            var textValue = (node != null) ? node.value : "";
            return textValue;

        },

        _isValidContact:function(itemNumber){
            //If there's no name or telephone then it's not a valid contact
            return (this._getValueById("name" + itemNumber) != "" || this._getValueById("phoneOne" + itemNumber) != "" || this._getValueById("phoneTwo" + itemNumber) != "");
        },
    });
});

更新: 经过大量的测试,我发现它不是导致错误的domConstruct.create语句,问题是表单元素有&#34; id:cccp&#34;并且我想要附加所创建的元素,此时为空。它在templateString中定义,您可以在源代码中看到它,但它在postCreate方法中仍然为null。那么现在的问题是,当加载templateString中的HTML时会触发什么事件?

1 个答案:

答案 0 :(得分:1)

最后我解决了这个问题,所以我在这里写下了解决方法,希望对某些人有所帮助! 我更改了templateString并将属性data-dojo-attach-point=\"form\"添加到了未找到的表单中。然后在postCreate方法中,我使用这个(this.form)访问了表单,它没有问题。该函数的最终实现结果如下:

postCreate: function () {
            // call base implementation
            this.inherited(arguments);

            //this._loadContacts(this.value);
            var node = domConstruct.create("fieldset", { id: "test" }, this.form); //this simple create instruction returns undefined here. 

            //Bind button
            this.connect(this.btnAdd, "onclick", dojo.partial(this._createContact, new Object()));

        },

我仍然不明白为什么dojo.byId("cccp")会返回null,但我很高兴我找到了解决问题的解决方法。干杯!