001// Copyright 2010, 2011 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.corelib.mixins; 016 017import org.apache.tapestry5.Block; 018import org.apache.tapestry5.ComponentResources; 019import org.apache.tapestry5.MarkupWriter; 020import org.apache.tapestry5.annotations.AfterRender; 021import org.apache.tapestry5.annotations.BeginRender; 022import org.apache.tapestry5.annotations.Events; 023import org.apache.tapestry5.annotations.MixinAfter; 024import org.apache.tapestry5.ioc.annotations.Inject; 025 026/** 027 * This mixin triggers <em>component event</em> notifications when the 028 * attached component enters its {@link BeginRender} and {@link AfterRender} 029 * render phases. A common use of this is to handle the "afterRender" 030 * event to generate client-side JavaScript for content just rendered via a 031 * {@link Block} (this is a common Ajax use case related to partial page 032 * rendering). Since AJAX requests don't trigger afterRender or beforeRender 033 * render phase events in the containing component or page, this mixin provides 034 * a way of accessing those events as component events. 035 * <p> 036 * An example using the {@link org.apache.tapestry5.corelib.components.Any Any} 037 * component within a zone: 038 * <pre> 039 * <div t:type="Zone" id="myZone"> 040 * <t:any t:mixins="RenderNotification"> 041 * <!-- zone content -> 042 * </div> 043 * </div> 044 * </pre> 045 * The {@link MarkupWriter} is passed as the event context to your event handler 046 * method(s), so your corresponding component or page class might look like: 047 * <pre> 048 * void onBeginRenderFromMyZone(MarkupWriter writer) 049 * { 050 * writer.element("p"); 051 * writer.write("before item render"); 052 * writer.end(); 053 * } 054 055 * void onAfterRenderFromMyZone(MarkupWriter writer) 056 * { 057 * writer.element("p"); 058 * writer.write("after item render"); 059 * writer.end(); 060 * } 061 * </pre> 062 * As an alternative, see the {@link org.apache.tapestry5.corelib.components.Trigger Trigger} 063 * component, which does something similar but as a component rather than a mixin. 064 * 065 * @since 5.2.0 066 * @tapestrydoc 067 */ 068@Events( 069{ "beginRender", "afterRender" }) 070@MixinAfter 071public class RenderNotification 072{ 073 @Inject 074 private ComponentResources resources; 075 076 void beginRender(MarkupWriter writer) 077 { 078 trigger(writer, "beginRender"); 079 } 080 081 void afterRender(MarkupWriter writer) 082 { 083 trigger(writer, "afterRender"); 084 } 085 086 private void trigger(MarkupWriter writer, String eventName) 087 { 088 resources.triggerEvent(eventName, new Object[] 089 { writer }, null); 090 } 091}