【问题标题】:closure - but still not the current var关闭 - 但仍然不是当前的 var
【发布时间】:2026-01-29 05:25:01
【问题描述】:

我有一个问题.. 当我提醒一个 var/obj(字段)时,我没有得到正确的返回

尝试用闭包解决它,但还是一样..

在 click() 之外返回当前和正确的对象(字段),但不在内部


编辑:jsfiddle

http://jsfiddle.net/CfxLx/

现在已经制作了一个 jsfiddle.. 当您想要编辑一行然后想要保存它时,警报框会返回您上次按下编辑的行的 id


this.insert_actions = function(row, id, table, elm, fields, options){
        var actions = $('<div class="actions"></div>').appendTo(elm);

        var _this = this;

        if(options.edit){
            alertobj(fields); // alerts object

            var btn_send = $('<input class="btn btn_margin_top" type="button" value="'+Lang.get('BTN_SAVE')+'" />').appendTo(actions)
                .click(function(){
                    alertobj(fields); // alerts object
                });

                ....

带关闭

this.insert_actions = function(row, id, table, elm, fields, options){
        var actions = $('<div class="actions"></div>').appendTo(elm);

        var _this = this;

        if(options.edit){
            alertobj(fields); // alerts object

            var btn_send = null;
            (function(fields){
                btn_send = $('<input class="btn btn_margin_top" type="button" value="'+Lang.get('BTN_SAVE')+'" />').appendTo(actions)
                    .click(function(){
                        alertobj(fields); // alerts object
                    });
            })(fields);

            ....

完整的功能

this.insert_actions = function(row, id, table, elm, fields, options){
    var actions = $('<div class="actions"></div>').appendTo(elm);

    if(options.edit){
        alert(fields.account_id_.dom.val());
        var btn_send = $('<input class="btn btn_margin_top" type="button" value="'+Lang.get('BTN_SAVE')+'" />').appendTo(actions)
            .click(function(){
                alert(fields.account_id_.dom.val());
                _this.put_row({
                    id : id
                }, {
                    index : row.index(),
                    insert : true
                }, table, row, fields);
            });

        var btn_cancel = $('<input class="btn btn_light btn_margin_top" type="button" value="'+Lang.get('BTN_CANCEL')+'" />').appendTo(actions)
            .click(function(){
                _this.get_rows({
                    id : id
                }, {
                    index : row.index()
                }, table, row);
            });

        var Tab = new Tabindex();

        for(var key in fields){
            (function(key){
                Tab.add(key, fields[key]);
                fields[key].dom.keydown(function(e){
                    if(Detect_key.get_keyname(e) == 'ENTER'){
                        btn_send.click();
                    }
                    else if(Detect_key.get_keyname(e) == 'ESC'){
                        btn_cancel.click();

                        return false;
                    }

                    return Tab.press(key, e);
                });
            })(key);
        }
    }
    else{
        var btn_edit = $('<input class="btn" type="button" value="'+Lang.get('BTN_EDIT')+'" />').appendTo(actions)
            .click(function(){
                _this.get_rows({
                    id : id
                }, {
                    index : row.index(),
                    edit : true
                }, table, row, fields);
            });

        var btn_delete = $('<input class="btn btn_light" type="button" value="'+Lang.get('BTN_DELETE')+'" />').appendTo(actions)
            .click(function(){
                Dialog.set_dialog({
                    headline : Lang.get('HDL_DELETE'),
                    body : Lang.get('DLG_DELETE_ACCOUNT'),
                    btns : [
                        {
                            value : Lang.get('BTN_DELETE'),
                            func : function(){
                                var A = new Ajax();
                                A.url = 'json.action.php?action=delete_'+table;
                                A.data = {
                                    id : id
                                };
                                A.success = function(response){
                                    if(response.error){
                                        var Cnt = new Content();
                                        Dialog.set_error({
                                            body : Cnt.error_body(response.error),
                                            btns : [
                                                {
                                                    value : Lang.get('BTN_OK'),
                                                    func : function(){
                                                        Dialog.rmv_error();
                                                    },
                                                    focus : true
                                                }
                                            ]
                                        });
                                    }
                                    else{
                                        row.remove();
                                        Dialog.rmv_dialog();
                                    }
                                };
                                A.send();
                            },
                            focus : true
                        },
                        {
                            value : Lang.get('BTN_CANCEL'),
                            func : function(){
                                Dialog.rmv_dialog();
                            },
                            type : 'light'
                        }
                    ]
                });
            });

        actions.css({
            opacity : 0
        });

        row.mouseover(function(){
            actions.fadeTo(0, 1);
        })
        .mouseout(function(){
            actions.fadeTo(0, 0);
        });
    }
};

【问题讨论】:

  • 首先,您尝试使用 立即函数 来解决问题,而不是闭包(尽管它也是闭包)。其次,您在这里不需要一个,因为您不在循环中。如果它没有提醒正确的值,那么是因为您使用错误的参数调用函数(或者您在未显示的部分以某种方式更改了对象)。
  • 正确的对象在click()之外被警告
  • @clarkk:那么请在jsfiddle.net 提供一个最小的工作示例。
  • @clarkk:Felix 对您引用的代码是正确的。问题一定出在其他地方,可能是您为简单起见而省略了的东西。
  • 现在已经添加了完整的功能...以后我会做一个jsfiddle :)

标签: javascript jquery


【解决方案1】:

我能看到的最有可能的问题是这一行,来自append_rows

var curr_fields = fields;

您似乎希望这会复制fields,但实际情况并非如此。 JavaScript 对象实际上是“通过引用”传递的,因此当您将 fields 的值分配给 curr_fields 时,您将 两个名称 赋予 一个对象

一个例子:

var a = { name: "foo" };
var b = a;
b.name = "bar";
alert(a.name); // Shows "bar"

闭包可以让你在循环的另一个迭代中再次使用同名,但它永远不会给你另一个同名对象的副本。 p>

Javascript 不提供任何内置方法来执行“深度复制”,您需要获取多层嵌套 fields 对象的完整副本。幸运的是,jQuery 使用了extend 方法,使用了deep 参数。

这意味着您可以通过将以下行替换为:

var curr_fields = $.extend(true, {}, fields);

它的作用是从一个新对象(中间参数{})开始,然后jQuery遍历fields中的每个对象和属性并将其复制到新对象中,然后将其存储在@ 987654334@.

【讨论】:

    最近更新 更多