代码之家  ›  专栏  ›  技术社区  ›  zhang_career

PATCH请求不适用于模糊,而适用于按键

  •  0
  • zhang_career  · 技术社区  · 8 年前

    我正在尝试创建一个内联编辑器,它将支持点击编辑和enter/blur保存。该环境包括PHP v5.6、jQuery v3.1、Laravel v5.2和MySQL。

    问题是,虽然使用enter保存有效,但模糊保存无效。

    Laravel DB:输入时收听保存:

    2016-08-10 12:01:45: select * from `user` where `user`.`id` = '15' limit 1
    2016-08-10 12:01:45: update `user` set `name` = '22222', `updated_at` = '2016-08-10 12:01:45' where `id` = '15'
    

    Laravel DB:听一下关于模糊的保存,注意根本没有“更新”查询:

    2016-08-10 11:21:53: select * from `user` where `user`.`id` = '15' limit 1
    

    <input> 文本已更改。我应该如何解决?

    inline-edit.js :

    var edit = $(".inline-edit");
    
    edit.click(function() {
        $('.ajax').html($('.ajax input').val());
        $('.ajax').removeClass('ajax');
        $(this).addClass('ajax');
        $OLDVAL = $.trim($(this).text());
        $(this).html('<input id="inline-editbox" type="text" value="' + $OLDVAL + '">');
        // focus and move cursor to the end of the editbox
        var inline_editbox = $('#inline-editbox');
        inline_editbox.focus();
        var editbox_value = inline_editbox.val();
        inline_editbox.val('');
        inline_editbox.val(editbox_value);
        // 
        inline_editbox.blur(function(event) {
            var formData = {
                tag: $(this).attr('id'),
                value: $('.ajax input').val(),
            };
            $.ajax({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
                },
                type: "PATCH",
                data: formData,
                dataType: 'json',
                success: function(data) {
                    $('.ajax').html($('.ajax input').val());
                    $('.ajax').removeClass('ajax');
                },
                error: function(xhr, status, error) {
                    console.warn(xhr.responseText);
                    alert(error);
                }
            });
        });
    });
    
    edit.keydown(function(event) {
        if (event.keyCode == 13) {
            var formData = {
                tag: $(this).attr('id'),
                value: $('.ajax input').val(),
            };
            $.ajax({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
                },
                type: "PATCH",
                data: formData,
                dataType: 'json',
                success: function(data) {
                    $('.ajax').html($('.ajax input').val());
                    $('.ajax').removeClass('ajax');
                },
                error: function(xhr, status, error) {
                    console.warn(xhr.responseText);
                    alert(error);
                }
            });
        }
    });
    

    Laravel route.php的一部分:

    Route::patch ('user/{id}',      ['as'=>'user.patch',  'uses'=>'UserController@update_ajax']);
    

    Laravel UserController.php的一部分:

    function update_ajax($id, UserCreateFormRequest $request)
    {
        $user = User::findOrFail($id);
        $tag  = $request->get('tag');
        if( $tag == 'name') {
            $user->update([
                'name'        =>    $request->get('value')
            ]);
        }
    
        if( $tag == 'email') {
            $user->update([
                'email'       =>    $request->get('value')
            ]);
        }
    
        if( $tag == 'isRegistered') {
            $user->update([
                'isRegistered'=>    $request->get('value')
            ]);
        }
    
        return response()->json([
            'status' => 'success',
            'msg' => 'Data created successfully',
        ]);
    }
    
    1 回复  |  直到 8 年前
        1
  •  0
  •   Community Tales Farias    4 年前

    你的主要问题似乎是 keydown .inline-editbox 而不是在 <input> ).

    然而,您的代码中也有很多重复和不必要的步骤,所以我重写了它,使其更清晰。

    以下内容:

    • 有一个单独的函数来执行Ajax调用(这使得Ajax呼叫和其余代码更容易理解,更重要的是更容易测试)
    • 使用jQuery的XHR承诺实现应用程序逻辑和Ajax逻辑的分离
    • 通过使用jQuery自定义事件 .trigger()
    • 当服务器更新失败时恢复原始值(您可以实现其他错误行为)
    • 正确处理HTML特殊字符(引号、尖括号)(您的版本在这方面有缺陷)

    完整代码:

    function patchUser(params) {
        return $.ajax({
            url: 'user/...',
            headers: {
                'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
            },
            type: "PATCH",
            data: JSON.stringify(params),
            contentType: "application/json"
        }).fail(function(xhr, status, error) {
            console.warn(xhr.responseText);
            alert(error);
        });
    }
    
    $(".inline-edit").click(function () {
        var $inlineEdit = $(this),
            curentValue = $.trim($inlineEdit.text());
    
        $inlineEdit.empty().addClass('ajax');
        $('<input>')
            .val(curentValue)
            .appendTo($inlineEdit)
            .on("blur", function () {
                $(this).trigger("contentchange");
            })
            .on("keydown", function (e) {
                if (e.keyCode == 13) $(this).trigger("contentchange");
            })
            .on("contentchange", function () {
                var newValue = $(this).val();
                if (newValue === curentValue) {
                    $inlineEdit
                        .text(curentValue)
                        .removeClass('ajax');
                } else {
                    patchUser({
                        tag: $inlineEdit.attr('id'),
                        value: newValue
                    }).done(function (data) {
                        $inlineEdit.text(data);
                    }).fail(function () {
                        $inlineEdit.text(curentValue);
                    }).always(function () {
                        $inlineEdit.removeClass('ajax');
                    });
                }
            })
            .focus();
    });
    

    单击以运行演示。我更换了 patchUser() 这里有一个模型。

    function patchUser(params) {
        var result = $.Deferred();
        result.resolve("Value saved: (" + params.value + ")");
        return result.promise();
    }
    
    $(".inline-edit").click(function () {
        var $inlineEdit = $(this),
            curentValue = $.trim($inlineEdit.text());
    
        $inlineEdit.empty().addClass('ajax');
        $('<input>')
            .val(curentValue)
            .appendTo($inlineEdit)
            .on("blur", function () {
                $(this).trigger("contentchange");
            })
            .on("keydown", function (e) {
                if (e.keyCode == 13) $(this).trigger("contentchange");
            })
            .on("contentchange", function () {
                var newValue = $(this).val();
                if (newValue === curentValue) {
                    $inlineEdit
                        .text(curentValue)
                        .removeClass('ajax');
                } else {
                    patchUser({
                        tag: $inlineEdit.attr('id'),
                        value: newValue
                    }).done(function (data) {
                        $inlineEdit.text(data);
                    }).fail(function () {
                        $inlineEdit.text(curentValue);
                    }).always(function () {
                        $inlineEdit.removeClass('ajax');
                    });
                }
            })
            .focus();
    });
    .inline-edit > input {
      width: 100%;
    }
    .ajax {
      border: 1px solid green;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div class="inline-edit" id="name">User Name</div>
    <div class="inline-edit" id="email">User Email</div>
    <div class="inline-edit" id="isRegistered">User IsRegistered</div>