asp.netajax:AJAX控制器来源: 发布时间:星期五, 2008年9月26日 浏览:103次 评论:0
现在,我们已经分析了基本的模型和创建视图的一些基本原则,接下来我们需要把它们“粘合”起来,创建一个终端用户真正可以进行交互的应用。在MVC的AJAX应用中,控制器负责这种“粘合”的实现。控制器需要响应用户动作并负责编制(orchestrate)视图和模型,这种本性决定了它将高度依赖于DOM事件的API。我们在第2章已经讨论了许多DOM事件模型,并且展示了如何以一种跨浏览器友好的方式给DOM元素附加事件。其中存在一个很重要的问题我们还没有考虑,这个问题即IE中存在的众所周知的内存泄漏问题。在IE中,内存泄露通常和DOM事件的附加联系在一起。在某些情况下,附加事件处理函数可能会造成DOM与JavaScript之间的循环引用。当一个匿名函数或者闭包被用来作为事件处理函数,并且,在这个匿名函数捕获的执行作用域里有一个被它所附加的HTML元素的引用时,将发生循环引用。下面的代码描述了这个概念: <html> <head> <script type="text/javascript"> var example = {}; example.init = function() { var customers = $("customerList"); customers.onclick = function() {this.style.fontWeight = "bold"}; } window.onload = example.init; </script> </head> <body> <div id="customerList"> <div>Jim</div><div>Bob</div><div>Mike</div> </div> </body> </html> 在example.init函数中,我们通过Id “customerList”获得对HTML元素的一个引用,然后设置这个HTML元素的onclick属性为一个匿名函数。和所有闭包一样,这个匿名函数捕获example.init函数的局部作用域(local scope),这个作用域包含一个customers变量,这个变量指向该匿名函数当前被附加到的同一个HTML元素,因此,产生了一个循环引用。就循环应用本身而言并不是一个问题,但是如果在页面重新加载之前不销毁它就会产生问题,因为这会消耗内存,因为IE的垃圾收集规则并不能对DOM对象与JavaScript之间的循环引用进行处理。这个问题在IE 6 和IE 7里都存在,所以我们需要一种避开问题的解决方案。我们需要采用一种通用且不唐突的方式来处理这个问题。尽管处理这个问题可能看上去很麻烦,尽管事实上它只是JavaScript带来的问题,但是这个内存泄露在复杂的应用里实际上往往会变得难以控制。尤其是企业应用,一次业务操作经常需要很长的时间,所以即使是很小的内存泄露都会开始累积并且极大地影响性能。为了处理这个问题,推荐的方法是保持对所有附加有事件处理函数的HTML元素的追踪,并且在随后Web页面卸载时将事件处理函数从HTML元素上分离。 为了帮助缓解事件管理所带来的麻烦,我们遵循单件模式创建了一个事件对象,事件可以通过它在跨浏览器的环境里被附加到HTML元素上或是从HTML元素分离。我们并不是要在事件管理器类上麻烦地创建一个正式的单件getInstance方法,而是利用JavaScript的特性创建一个唯一的EventManager对象,这个对象存在于Web页面的存活期间。事件管理的一般做法是在JavaScript里保持对所有被依附事件的追踪,对给定元素的所有特定事件只附加一个单独的事件处理函数,不再需要明确地将每个事件处理函数都附加到HTML元素上。这个单独的事件处理函数是EventManager对象上的一个方法,它负责把具体的事件委托到我们手动管理的每个事件处理函数。 这种处理事件的方法有几个重要的优点。尽管处理IE垃圾收集的问题是我们的事件管理策略中最主要的目标,但是它还有其他几个重要目标,这种处理事件的方法将有助于我们实现以下目标: l 以一种跨浏览器的方式附加事件处理函数; l 支持事件捕获(event capturing); l 提供对全局Event对象的访问; l 提供对触发事件的元素的访问; l 提供对事件处理所在元素的访问; l 防止IE内存泄露。 如果我们不在entAJAX的命名空间里使用静态方法和属性,而是以一个“适当的”单件类来封装对事件的管理,那么这个EventManager类的定义将如图3-7所示 。
0
相关文章
读者评论
发表评论 |