为什么全局对象的值正在改变而不仅仅是局部对象值?

时间:2016-06-07 09:29:24

标签: javascript

首先我要说的是,可能有些代码会有点复杂,可能需要进行审核,所以我对高级版进行了羞辱 : - <

无论如何,我的道歉是我的代码,我还添加了jsfiddle以便您可以查看实例。

jsfiddle

如果您想下载代码:

https://github.com/printmypic/js-form-generator

我遇到的问题是编辑后编辑,然后点击新表单,它会采用预览编辑表单的表单值。

我不明白为什么设置userForm的值而不是formGenerator.form的局部变量?

提前谢谢。

HTML:

    <button class="btn btn-success" id="newUser">New User</button>
    <table id="data" class="table table-striped table-hover table-bordered dt-responsive nowrap dataTable no-footer" cellspacing="0" width="100%" role="grid" aria-describedby="data_info" style="width: 100%;">
            <thead>
                        <tr role="row"><th class="sorting_asc" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-sort="ascending" aria-label="id: activate to sort column descending" style="width: 50px;">id</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="user: activate to sort column ascending" style="width: 122px;">user</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="password: activate to sort column ascending" style="width: 214px;">password</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="email: activate to sort column ascending" style="width: 201px;">email</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="phone: activate to sort column ascending" style="width: 42px;">phone</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="full name: activate to sort column ascending" style="width: 92px;">full name</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="country: activate to sort column ascending" style="width: 51px;">country</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="pids: activate to sort column ascending" style="width: 221px;">pids</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="type: activate to sort column ascending" style="width: 29px;">type</th><th class="sorting" tabindex="0" aria-controls="data" rowspan="1" colspan="1" aria-label="bid: activate to sort column ascending" style="width: 21px;">bid</th></tr></thead>
                    <tbody>
                    <tr role="row" class="odd"><td class="sorting_1"><div class="btn-group">
            <button class="btn dropdown-toggle" data-toggle="dropdown">Action <span class="caret"></span></button>
            <ul class="dropdown-menu">
            <li class=""><a class="action editUser" data-id="1">Edit</a></li><li class=""><a class="action deleteUser" data-id="">Delete</a></li></ul></div></td><td>tal</td><td>222a3962a50d89a</td><td>someuser@gmail.com</td><td>34214324</td><td>frw</td><td>dsad</td><td>dsad</td><td>Admin</td><td></td></tr></tbody>
        </table>
<div id="myModal" class="modal fade">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title" id="modaltitle">Modal title</h4>
        </div>
        <div class="modal-body clearfix" id="modalbody">
        </div>
        <div class="modal-footer">
            <button id="modalcancel" type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            <button id="modalsave" type="button" class="btn btn-primary">Save changes</button>
        </div>
    </div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->

JS

function showModal(modalContent,callback) {
    for (i in modalContent) {
        if (i === 'modalcancel' || i === 'modalsave') {
            $('#' + i).attr('onclick', modalContent[i]);
            if (modalContent[i] === '') {
                $('#' + i).text('close').hide();
            } else {
                $('#' + i).text('save').show();
            }
        } else if ($.isFunction(modalContent[i])) {
            $('#' + i).html(modalContent[i]());
        } else {
            $('#' + i).html(modalContent[i]);
        }
    }
    $('#myModal').modal();
    if($.isFunction(callback)){
        callback();
    }
}

var formGenerator = {
    tableSelector: '#data',
    tableHeaders: '#data th',
    formId: 'newUserForm',
    form: {},
    skipVars: ['id'],
    init: function (config, callback) {
        if (config.formId) {
            this.formId = config.formId;
        }

        if (config.tableHeaders) {
            this.tableHeaders = config.tableHeaders;
        }

        if (config.editElement) {
            this.form = this.setValuesByTableRow(config.editElement, config.form);
        } else {
            this.form = config.form;
        }

        if($('#'+this.formId).size()){
            $('#'+this.formId).remove();
        }

        var $form = $('<form id="'+this.formId+'" autocomplete="off" class="form-horizontal"></form>');
        var that = this;

        $(this.tableHeaders).each(function () {
            var name = $(this).text().toLowerCase().replace(/ /g, '_');
            if ($.inArray(name, that.skipVars) !== -1 || typeof (that.form[name]) === 'undefined') {
                return;
            }
            $formElement = that.createFormElement(that.form[name].name, that.form[name].type, that.form[name].value);
            $formElement.appendTo($form);
        });

        if(callback && $.isFunction(callback)){
            setTimeout(function () {
                callback()
            }, '200');
        }
        return this.htmlForm = $form[0].outerHTML;

    },
    createFormElement: function (name, type, value) {
        var $inputContainer = $('<div class="form-group col-md-6"></div>');
        var $container = $('<div class="form-group col-md-12"></div>');
        switch (type) {
            case 'password':
            case 'text':
            case 'email':
            case 'hidden':
            case 'number':
            value = value ? value : '';
            $element = $('<input autocomplete="off" type="' + type + '" class="form-control" id="' + name + '" placeholder="' + name.replace(/_/g, ' ') + '" name="' + name + '" value="' + value + '" />');
            break;
            case 'select':
            var options = this.getOptions(this.form[name].selectData,value);
            $element = $('<select class="form-control" id="' + name + '" placeholder="' + name + '" name="' + name + '">' + options + '</select>');
            break;
        }
        $inputContainer.append($element);
        $labelContainer = $('<div class="form-group col-md-6"><label for="' + name + '">' + name.replace(/_/g, ' ') + '</label></div>');
        $container.append($labelContainer);
        return $container.append($inputContainer);
    },
    getColByThTr: function (thText, $element, tableSelector) {
        var landingIndex = $(tableSelector + ' th:contains(' + thText + ')').index() + 1;
        return $element.closest('tr').find('td:nth-child(' + landingIndex + ')');
    },
    setValuesByTableRow: function ($element, form) {
        var editForm = form;
        for (i in editForm) {
            var th = i.replace(/_/g, ' ');
            if (editForm[i].type === 'select') {
                editForm[i].selectData.selected = this.getColByThTr(th, $element, this.tableSelector).text();
            } else if (editForm[i].type === 'password') {
                editForm[i].value = '';
            } else {
                editForm[i].value = this.getColByThTr(th, $element, this.tableSelector).text().trim();
            }
        }
        return editForm;
    },
    formatSelectArr: function (arr, nasted, selectedItem) {
        var formattedSelectArr = [];
        if (!selectedItem) {
            formattedSelectArr.push({'title': 'Select', 'selected': true, 'value': ''});
        }
        var value, title = '';
        for (i in arr) {
            title = arr[i];
            if (nasted) {
                value = i;
            } else {
                value = arr[i];
            }
            if (selectedItem === arr[i]) {
                selected = true;
            } else {
                selected = false;
            }
            formattedSelectArr.push({'title': title, 'selected': selected, 'value': value});
        }
        return formattedSelectArr;
    },
    getOptions: function (arr) {
        var data = this.formatSelectArr(arr.data, arr.nasted, arr.selected);
        var html = '';
        for (i in data) {
            selected = (data[i].selected) ? 'selected' : '';
            html += '<option value="' + data[i].value + '" ' + selected + '>' + data[i].title + '</option>';
        }
        return html;
    }

};



var userTypes = {"1":"Admin","2":"API"};
var bids = ["bid1","bid2"];
var countriesArr = ["Afghanistan","Albania","Algeria","American Samoa","Andorra","Angola","Anguilla","Antarctica","Antigua and Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia and Herzegovina","Botswana","Bouvet Island","Brazil","British Indian Ocean Territory","Brunei Darussalam","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Canada","Cape Verde","Cayman Islands","Central African Republic","Chad","Chile","China","Christmas Island","Cocos (Keeling) Islands","Colombia","Comoros","Congo","Congo, the Democratic Republic of the","Cook Islands","Costa Rica","Cote DIvoire","Croatia","Cuba","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Ethiopia","Falkland Islands (Malvinas)","Faroe Islands","Fiji","Finland","France","French Guiana","French Polynesia","French Southern Territories","Gabon","Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guadeloupe","Guam","Guatemala","Guinea","Guinea-Bissau","Guyana","Haiti","Heard Island and Mcdonald Islands","Holy See (Vatican City State)","Honduras","Hong Kong","Hungary","Iceland","India","Indonesia","Iran, Islamic Republic of","Iraq","Ireland","Israel","Italy","Jamaica","Japan","Jordan","Kazakhstan","Kenya","Kiribati","Korea, Democratic Peoples Republic of","Korea, Republic of","Kuwait","Kyrgyzstan","Lao Peoples Democratic Republic","Latvia","Lebanon","Lesotho","Liberia","Libyan Arab Jamahiriya","Liechtenstein","Lithuania","Luxembourg","Macao","Macedonia, the Former Yugoslav Republic ","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Martinique","Mauritania","Mauritius","Mayotte","Mexico","Micronesia, Federated States of","Moldova, Republic of","Monaco","Mongolia","Montserrat","Morocco","Mozambique","Myanmar","Namibia","Nauru","Nepal","Netherlands","Netherlands Antilles","New Caledonia","New Zealand","Nicaragua","Niger","Nigeria","Niue","Norfolk Island","Northern Mariana Islands","Norway","Oman","Pakistan","Palau","Palestinian Territory","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Pitcairn","Poland","Portugal","Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Helena","Saint Kitts and Nevis","Saint Lucia","Saint Pierre and Miquelon","Saint Vincent and the Grenadines","Samoa","San Marino","Sao Tome and Principe","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Georgia and the South Sandwich Isl","Spain","Sri Lanka","Sudan","Suriname","Svalbard and Jan Mayen","Swaziland","Sweden","Switzerland","Syrian Arab Republic","Taiwan, Province of China","Tajikistan","Tanzania, United Republic of","Thailand","Timor-Leste","Togo","Tokelau","Tonga","Trinidad and Tobago","Tunisia","Turkey","Turkmenistan","Turks and Caicos Islands","Tuvalu","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States","United States Minor Outlying Islands","Uruguay","Uzbekistan","Vanuatu","Venezuela","Viet Nam","Virgin Islands, British","Virgin Islands, U.s.","Wallis and Futuna","Western Sahara","Yemen","Zambia","Zimbabwe","Montenegro"];
var userForm = {
    'full_name': {type: 'text', name: 'full_name',value:''},
    'user': {type: 'text', name: 'user',value:''},
    'password': {type: 'password', name: 'password',value:''},
    'bid': {type: 'select', name: 'bid', selectData: {'data':bids, 'nasted':false, 'selected':''},value:''},
    'pids': {type: 'text', name: 'pids',value:''},
    'phone': {type: 'number', name: 'phone',value:''},
    'type': {type: 'select', name: 'type', selectData: {'data':userTypes, 'nasted':true, 'selected':'Affiliate'},value:''},
    'country': {type: 'select', name: 'country', selectData:  {'data':countriesArr, 'nasted':false, 'selected':'Israel'},value:''},
    'email': {type: 'email', name: 'email',value:''},
};


myForm = formGenerator;


function editUser(element, id) {
    $element = $(element).closest('tr');

    showModal({
        'modalsave': '',
        'modalcancel': '',
        'modaltitle': 'Info',
        'modalbody': '' + myForm.init(
        {
            'tableHeaders': '#data th',
            'form': userForm,
            'editElement':$element
        }
        ) + ''
    });
}

function newUserForm(){
    showModal({
        'modalsave': 'alert(\'save\')',
        'modalcancel': '',
        'modaltitle': 'Info',
        'modalbody': '' + myForm.init(
        {
            'tableHeaders': '#data th',
            'form': userForm,
            'editElement':false
        }
        ) + ''
    });
}

$(function(){
    $('#newUser').on('click',function(){newUserForm();});
    $('.editUser').on('click',function(){editUser(this,$(this).data('id'));});
});

1 个答案:

答案 0 :(得分:1)

从此     formId: 'newUserForm'

对此     this.formId = config.formId;

通过引用传递。所以你在formGenerator中的formId实际上是newUserForm的引用。这有意义吗?

默认情况下,Javascript通过引用传递对象。如果您不想这样,您可能想要编写克隆函数或执行浅/深复制。 jQuery使您可以轻松完成此操作。

var newUserForm2 = jQuery.extend({},newUserForm)

这将使对newUserForm2的更改不会影响newUserForm。

请阅读this thread了解详情