回发后元素在 jQuery 对象中保留原始值
我正在将 ASP.NET 3.5 与糟糕的 UpdatePanel、jQuery.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
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.
也许你应该在 ajax updatepanel 请求完成时重新初始化对象干杯
,
镍丁
maybe you should re-init the objects when the ajax updatepanel request completes
Cheers,
Nitin
无论如何,我想出的解决方案是 Paul Irish 的 基于标记的不显眼的全面 DOM 就绪执行 和 @NitinJS' / @Ethan 的答案。
在我的 JavaScript 底部添加:
在我的 MasterPage 的 aspx 中,我将 body 标记修改为:
在我的 MasterPage 的 aspx 中代码隐藏声明,我添加了:
在我的 MasterPage 的代码隐藏 Page.PreRender 处理程序中,我添加了:
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:
In my MasterPage's aspx, I modified the body tag to:
In my MasterPage's code-behind declarations, I added:
In my MasterPage's code-behind Page.PreRender handler, I added: