取消的事件不会将 RadTextBox 恢复为初始值

Canceled event is not reverting RadTextBox to initial value

最近,我重构了 javascript 以更好地利用闭包和调用。

问题

设置 RadButton 客户端随附的 telerik eventArgument (e) cancel 属性 (to true) OnValueChanging 事件是 不再 将值设置回 oldValueinitialValue

Paysheet.UI

window.Paysheet.UI.WorkRate = { 
    "OnValueChanging"   : function (sender, e, args) {
        /// <summary>Entry-Point Function; initializes and calls 'Paysheet.XHR.POST', evaluates the response; Initializes and invokes the proper RadWindow/RadAlert/RadPrompt</summary>
        /// <param name="sender" type="Telerik.Web.UI.RadTextBox">The Telerik Control that raises the event</param>
        /// <param name="e" type="Telerik.Web.UI.InputValueChangingEventArgs">The Telerik Event</param>
        /// <param name="args" type="JSON">JSON that is to be processed by the handler, and posted</param>

        args = Paysheet.Common.GetDataKeyValues(sender);
        args.RequestorID = window.Paysheet.Requestor.ID;
        //args.AuthToken = window.Paysheet.Requestor.AuthToken;

        args.Scope = "PaysheetItem";
        args.PaysheetItemScope = "PayRate";
        args.RateType = "WorkRate";
        args.Rate = e.get_newValue();
        args._uri = "Paysheet/" + args.PayPeriodEmployeeID + "/PayRate/Modify";

        console.log("(1st) XHR POST => args: %o", args);
        return Paysheet.Common.Func(Paysheet.Common.OnValueChangingResultHandler, sender, e, args);
    }
};

上面的代码是从 RadTextBox OnValueChanging EventHandler 调用的,如下所示:

"valueChanging": function(sender, e) {
    args = {};
    console.log(" [EventOccurring] - sender: %o - e: %o - args: %o", sender, e, args); 
    e._cancel = !(Paysheet.UI.WorkRate.OnValueChanging(sender, e, args));
}

Paysheet.XHR

 window.Paysheet.XHR = {
    "POST": function (uri, jsonData) {
        /// <summary>Encapsulates the XmlHttpRequest object; posts the given data (JSON string) to a specified handler page and returns the JSON object</summary>
        /// <param name="url" type="String">URI</param>
        /// <param name="jsonData" type="String">JSON Data to be posted</param>

        uri = uri || jsonData._uri;
        var xhr = new XMLHttpRequest();
        xhr.open("POST", uri, false); // synchronous call
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send(JSON.stringify(jsonData));
        return (xhr.status == 200) ? JSON.parse(xhr.response) : { "isValid": false, "StatusCode": 500 };
    }
};

Paysheet.Common

window.Paysheet.Common = {
    "Func": function (func, sender, e, args) {
        console.log("Call to func..");
        var result = func(sender, e, args, (Paysheet.XHR.POST(args._uri, args) || { "isValid": false, "isOverrideable" : false, "StatusCode": 500 }));
        console.log("result of call: %o", result);
        return result;
    },
    "GenericResultHandler": function (result, handlers) {
        result = result || { "isValid": false, "isOverrideable": false, "StatusCode": 500 };

        if (result.StatusCode != 200) {
            console.log("[ERROR] - [RadAlert] Invoked...");
            //the result.message show be more domain specific.
            radalert(result.message || "Internal Error Occurred!", 400, 350, result.title || "Alert - Error", null, null);

        } else if (result.isValid) {

            console.log("[APPROVED]");
            handlers.approve();

            return true;
        } else if (result.isOverrideable) {

            console.log("[OVERRIDE] - [RadPrompt] Invoked...");
            handlers.override();
        } else {

            console.log("[REJECTED] - [RadAlert] Invoked...");
            handlers.reject();

            //the result.message show be more domain specific.
            radalert(result.message || "The state of this data prevents any modifications; Overriding is not an option.",
                400, 350,
                result.title || "Alert - Denied",
                null, null);
        }

        // ultimately, the caller will be a cancelable telerik event.
        //    by convension, the result is inverted/flipped: thus, this resolves to 'e.set_cancel = !([return])'
        //    note: override will have to set the value explicitly without triggering this event in the (presumed) asynchronous method call to 'handlers.override';
        return false;
    },
    "GenericOverrideResultHandler": function (result, handlers) {
        result = result || { "isValid": false, "StatusCode": 500, "isOverrideable" : false };            

        if (result.StatusCode != 200) {
            console.log("[OVERRIDE ERROR] - [RadAlert] Invoked...");
            radalert(result.message || "Internal Error Occurred!", 400, 350, result.title || "Alert - Error", null, null);
        } else if (result.isValid) {
            console.log("[OVERRIDE APPROVED]");
            handlers.approve();
        } else {
            console.log("[OVERRIDE REJECTED] - [RadAlert] Invoked...");

            //the result.message show be more domain specific.
            radalert(result.message || "Override was denied, no modification made to stored data!", 400, 350, result.title || "Alert - Override Denied", null, null);
            handlers.reject();
        }
    },
    "OnValueChangingResultHandler": function (sender, e, args, result) {
        return Paysheet.Common.GenericResultHandler(result, { "approve": approve, "override": override, "reject": reject });

        function approve() {
            var d = Paysheet.Common.GetDataKeyValues(sender);
            var DaysCell = sender.get_parent().get_cell("Days");
            if (DaysCell["set_value"]) {
                DaysCell.set_value(result.content.Days);
            } else {
                DaysCell.innerHTML = result.content.Days;
            }

            var GrossCell = sender.get_parent().get_cell("Gross");
            if (GrossCell["set_value"]) {
                GrossCell.set_value(result.content.Gross);
            } else {
                GrossCell.innerHTML = result.content.Gross;
            }
        }

        function override() {
            radprompt(result.message, callback, 400, 350, null, result.title || "Prompt - Override", false);

            function callback(promptArgs) {
                promptArgs = promptArgs || { "override": false, "note": "" };

                if (promptArgs.override && promptArgs.note.length > 0) {
                    args.Override = promptArgs.override;
                    args.OverrideNote = promptArgs.note;
                    console.log("(2nd) XHR POST [start] => args: %o", args);
                    var result = Paysheet.XHR.POST(args._uri, args);
                    console.log("(2nd) XHR POST [finished] - results: %o", result);
                    if ((result) ? result.isValid : false) {
                        console.log("[SUCCESS]");
                        sender._setNewValue(e.get_newValue());
                        var d = Paysheet.Common.GetDataKeyValues(sender);
                        //Update Gross;
                        var DaysCell = sender.get_parent().get_cell("Days");
                        if (DaysCell["set_value"]) {
                            DaysCell.set_value(result.content.Days);
                        } else {
                            DaysCell.innerHTML = result.content.Days;
                        }

                        var GrossCell = sender.get_parent().get_cell("Gross");
                        if (GrossCell["set_value"]) {
                            GrossCell.set_value(result.content.Gross);
                        } else {
                            GrossCell.innerHTML = result.content.Gross;
                        }
                    } else {
                        console.log("[FAILED]");
                        sender._SetValue(sender._initialValueAsText);
                        sender.updateDisplayValue();
                        if (result.StatusCode == 200) {
                            console.log("... Denied [RadAlert] Invoked...");
                            radalert(result.message || "Override request denied!", 400, 350, result.title || "Alert - Override Denied", null, null);
                        } else //if (result.StatusCode == 500)
                        {
                            console.log("... Error [RadAlert] Invoked...");
                            radalert(result.message || "Internal Error Occurred!", 400, 350, result.title || "Alert - Error", null, null);
                        }
                    }
                } else {
                    // ensuring the control retains the same value; for the prompt is async;
                    sender._SetValue(e.get_oldValue());
                    sender.updateDisplayValue();
                }
            }
        }

        function reject() {
            // neither of the following lines should be necessary, for the GenericResultHandler returns true|false to `e._cancel`
            // sender._SetValue(e.get_oldValue()); //This line works
            // e._cancel = true; //This line does not work
        }
    }
};

我已经逐步完成了这段代码,并进入了 telerik 的代码。它似乎确实使用 _initialValueAsText 调用 _SetValue。我只是似乎并没有实际应用。

如果我在 'reject' 函数中明确设置事件的取消 属性。它表现出同样的问题。

如果我将发件人的值明确设置为旧值,它会起作用。


编辑:我已经注释掉了xhr.send行(同步调用)——强制POST函数为return{ "isValid" : false, "isOverrideable" : false, "StatusCode": 500 } - 问题仍然存在。

在将 truefalse 分配给 event._canceled 之前的某个时候调用 sender._setHiddenValue(e.get_newValue()) 可以更正问题..


_setHiddenValue(value) 有条件地将 sender_text_value 字段设置为新值:它检查传递的 value 与现有 _value,如果相同,则函数退出,不赋值。它以 truefalse 值指示分配是否发生。

If/wheneventArg_canceled字段设置为true,内部事件处理器调用sender._SetValue(sender._initialValueAsText);在该过程中,调用了 sender._setHiddenValue(sender._initialValueAsText)