回发后元素在 jQuery 对象中保留原始值

发布于 2024-11-09 11:23:24 字数 4156 浏览 3 评论 0原文

我正在将 ASP.NET 3.5 与糟糕的 UpdatePaneljQuery.delegate()JavaScript 对象结合使用文字。

我使用 jQuery.delegate() 来持久化事件处理程序,这些处理程序确实会按预期在 PostBack 之后触发。

问题在于 jQuery 对象存储在 init() 上的对象文字属性中,它们保留在 ASP.NET PostBack 之前拥有的值>。

这是我的 JavaScript


SFAIC


SFAIC = 
{
    masterPages: { cs: "CS_", cp: "CP_" },
    contentPages: { cs: "CSContent_", cp: "CPContent_" },
    
    isSecurePage  : false,

    $body         : undefined,
    $container    : undefined,
    $updatePanel  : undefined,

    $textBox      : undefined,
    $errorLabel   : undefined
};

SFAIC.init()


SFAIC.init = function () 
{ 
    log( "--> SFAIC.init() fired" );

    var self = this; 

    self.$body        = $( "body" );
    self.$container   = self.$body.find( "#container" );
    self.$updatePanel = self.getCSMasterElement( "UpdatePanel1", self.$container );
    self.$textBox     = self.getContentElement( "TextBox1" );
    self.$errorLabel  = self.getContentElement( "ErrorLabel1" );
     
    self.$updatePanel.delegate( self.$textBox.selector, "blur", function () 
    { 
       self.validateRequired( self.$textBox, self.$errorLabel ); 
    });
    
    self.$textBox.focus();
};

SFAIC.validateRequired()


SFAIC.validateRequired = function ( $element, $errorLabel ) 
{
    if ( $element.val().length === 0 ) { $errorLabel.text( "Required" ); }
    else { $errorLabel.text( "" ); }
};


鉴于上述,当 SFAIC.init() 被触发时, self.textBox< /code> 被分配给它的 jQuery 对象。我想这就是我的困惑。我认为当您调用 .val() 时,它会立即返回该元素中的值。如果您调用服务器并更改控件的值,然后返回渲染元素的更改值,则 jQuery 对象似乎不知道该更改?

我这里错了吗?

我需要做什么来保持对元素的实时引用,以便在页面回发后可以获取当前值?


根据 @DaveLong 编辑请求:


SFAIC.getCSMasterElement()


SFAIC.getCSMasterElement = function ( id, $context ) 
{ 
    return SFAIC.getElement( SFAIC.masterPages.cs, id, $context ); 
};

SFAIC.getCPMasterElement()


SFAIC.getCPMasterElement = function ( id, $context ) 
{ 
    return SFAIC.getElement( SFAIC.masterPages.cp, id, $context ); 
};

SFAIC.getContentElement()


SFAIC.getContentElement = function ( id, $context ) 
{ 
    return SFAIC.getElement
    ( 
        ( SFAIC.isSecurePage ) ? SFAIC.contentPages.cp : SFAIC.contentPages.cs, 
        id, 
        $context 
    ); 
};

SFAIC.getElement()


SFAIC.getElement = function ( page, id, $context ) 
{
    selector = SFAIC.getElementIdSelector( page, id );
    
    return ( selector ) 
        ? ( $context && $context.length ) 
            ? $context.find( selector ) 
            : SFAIC.$body.find( selector )
        : undefined;
};

SFAIC.getElementIdSelector()


SFAIC.getElementIdSelector = function ( page, id ) 
{ 
    var prefix = SFAIC.getElementPrefix( page );
    return ( prefix && id ) ? "#" + prefix + id : undefined;
};

SFAIC.getElementPrefix()


SFAIC.getElementPrefix = function ( page ) 
{   
    switch ( page ) 
    {
        case SFAIC.masterPages.cs : return SFAIC.masterPages.cs;
        case SFAIC.masterPages.cp : return SFAIC.masterPages.cp + SFAIC.masterPages.cs;
        case SFAIC.contentPages.cs : return SFAIC.masterPages.cs + SFAIC.contentPages.cs;
        case SFAIC.contentPages.cp : return SFAIC.masterPages.cp + SFAIC.masterPages.cs + SFAIC.contentPages.cs + SFAIC.contentPages.cp;                
    }
};

I am using ASP.NET 3.5 combined with the atrocious UpdatePanel, jQuery.delegate(), and JavaScript object literals.

I use jQuery.delegate() to persist the event handlers, which do get triggered after the PostBack, as expected.

The issue is with the jQuery objects stored in object literal properties on init() where they keep the values they had prior to the ASP.NET PostBack.

Here is my JavaScript :

SFAIC


SFAIC = 
{
    masterPages: { cs: "CS_", cp: "CP_" },
    contentPages: { cs: "CSContent_", cp: "CPContent_" },
    
    isSecurePage  : false,

    $body         : undefined,
    $container    : undefined,
    $updatePanel  : undefined,

    $textBox      : undefined,
    $errorLabel   : undefined
};

SFAIC.init()


SFAIC.init = function () 
{ 
    log( "--> SFAIC.init() fired" );

    var self = this; 

    self.$body        = $( "body" );
    self.$container   = self.$body.find( "#container" );
    self.$updatePanel = self.getCSMasterElement( "UpdatePanel1", self.$container );
    self.$textBox     = self.getContentElement( "TextBox1" );
    self.$errorLabel  = self.getContentElement( "ErrorLabel1" );
     
    self.$updatePanel.delegate( self.$textBox.selector, "blur", function () 
    { 
       self.validateRequired( self.$textBox, self.$errorLabel ); 
    });
    
    self.$textBox.focus();
};

SFAIC.validateRequired()


SFAIC.validateRequired = function ( $element, $errorLabel ) 
{
    if ( $element.val().length === 0 ) { $errorLabel.text( "Required" ); }
    else { $errorLabel.text( "" ); }
};


Given the above, when SFAIC.init() is fired, self.textBox is assigned to its jQuery object. I guess herein lies my confusion. I thought that when you call .val(), it would return the value of what's in that element right then. In the case where you make a call to the server and change the value of the control which then comes back rendering the changed value of the element, it seems that the jQuery object doesn't know about that change?

Am I wrong here?

What do I need to do to keep a real-time reference to the element, so that I can get the current value after the page is posted back?

Edit request per @DaveLong :

SFAIC.getCSMasterElement()


SFAIC.getCSMasterElement = function ( id, $context ) 
{ 
    return SFAIC.getElement( SFAIC.masterPages.cs, id, $context ); 
};

SFAIC.getCPMasterElement()


SFAIC.getCPMasterElement = function ( id, $context ) 
{ 
    return SFAIC.getElement( SFAIC.masterPages.cp, id, $context ); 
};

SFAIC.getContentElement()


SFAIC.getContentElement = function ( id, $context ) 
{ 
    return SFAIC.getElement
    ( 
        ( SFAIC.isSecurePage ) ? SFAIC.contentPages.cp : SFAIC.contentPages.cs, 
        id, 
        $context 
    ); 
};

SFAIC.getElement()


SFAIC.getElement = function ( page, id, $context ) 
{
    selector = SFAIC.getElementIdSelector( page, id );
    
    return ( selector ) 
        ? ( $context && $context.length ) 
            ? $context.find( selector ) 
            : SFAIC.$body.find( selector )
        : undefined;
};

SFAIC.getElementIdSelector()


SFAIC.getElementIdSelector = function ( page, id ) 
{ 
    var prefix = SFAIC.getElementPrefix( page );
    return ( prefix && id ) ? "#" + prefix + id : undefined;
};

SFAIC.getElementPrefix()


SFAIC.getElementPrefix = function ( page ) 
{   
    switch ( page ) 
    {
        case SFAIC.masterPages.cs : return SFAIC.masterPages.cs;
        case SFAIC.masterPages.cp : return SFAIC.masterPages.cp + SFAIC.masterPages.cs;
        case SFAIC.contentPages.cs : return SFAIC.masterPages.cs + SFAIC.contentPages.cs;
        case SFAIC.contentPages.cp : return SFAIC.masterPages.cp + SFAIC.masterPages.cs + SFAIC.contentPages.cs + SFAIC.contentPages.cp;                
    }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

披肩女神 2024-11-16 11:23:24

UpdatePanel 从 DOM 中删除整个目标,并用响应中的新标记替换它。这并不是说您的变量持有旧值,而是它们持有对原始标记的引用。您需要“重新初始化”才能获取 DOM 中新节点的引用。

The UpdatePanel removes the entire target from the DOM and replaces it with new markup from the response. It isn't that your vars are holding old values, it is that they are holding references to the original markup. You need to "reinitialize" in order to obtain references to the new nodes in the DOM.

┊风居住的梦幻卍 2024-11-16 11:23:24

也许你应该在 ajax updatepanel 请求完成时重新初始化对象干杯

<script type="text/javascript" language="javascript">
     Sys.WebForms.PageRequestManager.getInstance().add_endRequest(ReInitiate); 
     function ReInitiate(sender, args)
     {
        //re-initialize the objects 
        //add code here 
     } 
</script>


镍丁

maybe you should re-init the objects when the ajax updatepanel request completes

<script type="text/javascript" language="javascript">
     Sys.WebForms.PageRequestManager.getInstance().add_endRequest(ReInitiate); 
     function ReInitiate(sender, args)
     {
        //re-initialize the objects 
        //add code here 
     } 
</script>

Cheers,
Nitin

夜还是长夜 2024-11-16 11:23:24

无论如何,我想出的解决方案是 Paul Irish 的 基于标记的不显眼的全面 DOM 就绪执行 和 @NitinJS' / @Ethan 的答案。

在我的 JavaScript 底部添加:

UTIL = {

    fire : function(func, funcname) {

        var namespace = SFAIC;
        funcname = (funcname === undefined) ? "init" : funcname;

        if (func !== "" && 
            namespace[func] && 
            typeof namespace[func][funcname] == "function") { 

            namespace[func][funcname](); 

        }

    },

    loadEvents : function() {

        var bodyId = document.body.id;

        UTIL.fire("common");
        UTIL.fire(bodyId);

    }

};

// Fire events on initial page load.
UTIL.loadEvents();

// Fire events for partial postbacks.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(UTIL.loadEvents);

在我的 MasterPage 的 aspx 中,我将 body 标记修改为:

<body id="<%=bodyId%>">

在我的 MasterPage 的 aspx 中代码隐藏声明,我添加了:

Public bodyId As String = String.Empty

在我的 MasterPage 的代码隐藏 Page.PreRender 处理程序中,我添加了:

bodyId = MyBase.GetType.BaseType.Name

For what it's worth, the solution I came up with was a customized version of Paul Irish's Markup-based unobtrusive comprehensive DOM-ready execution and @NitinJS' / @Ethan's answers.

At the bottom of my JavaScript I added:

UTIL = {

    fire : function(func, funcname) {

        var namespace = SFAIC;
        funcname = (funcname === undefined) ? "init" : funcname;

        if (func !== "" && 
            namespace[func] && 
            typeof namespace[func][funcname] == "function") { 

            namespace[func][funcname](); 

        }

    },

    loadEvents : function() {

        var bodyId = document.body.id;

        UTIL.fire("common");
        UTIL.fire(bodyId);

    }

};

// Fire events on initial page load.
UTIL.loadEvents();

// Fire events for partial postbacks.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(UTIL.loadEvents);

In my MasterPage's aspx, I modified the body tag to:

<body id="<%=bodyId%>">

In my MasterPage's code-behind declarations, I added:

Public bodyId As String = String.Empty

In my MasterPage's code-behind Page.PreRender handler, I added:

bodyId = MyBase.GetType.BaseType.Name
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文