PureMVC example - InterestsMediator - Efficient Notification Mapping

Tags:

I've been working with PureMVC for a while now. Like anything - there are parts I love, and parts a I really don't. One thing that becomes cumbersome is creating mediators for parts of the application that only have to handle one or two redundant notifications.
For this I set out to create a custom mediator to handle these type of situations across an application. I went ahead with several goals -- to keep the view decoupled from the framework, to be able to add and remove a views interest in a certain property, and to fix race conditions similarly to how bindings do.

For example, In the small example application I have attached at this bottom of this post there are three (color coded) sections all of which need to know about a property set in another section of the application. This is the only property these sections need to know from the application, and it would be overkill to instantiate mediators for every one of them. They instead use an InterestEvent to register themselves as a party interested in this event. They also implement an interface which extends from the IInterest marker interface and has a setter for the text. When the text is changed, the application mediator hears this and sends a notification. Inside the InterestsMediator you define the relationship between notification names and interfaces, so when a view declares it's interest through an event, the InterestsMediator creates a map of views that are interested in certain notifications.
The mapping occurs within the protected listNotificationMappings method.
Mappings look like this.

 
override protected function listNotificationMappings():Array{
return [
	{name : NotificationNames.MAIN_TEXT_CHANGE, type : ITextInterest, method : 'theText'},
	]
}
 

The views, for various reasons can also disassociate themselves as interested parties. Inside the example app you can the click the 'remove interest' button on different views and you'll see they no longer get updates, but as soon as you click the add interest button it will start receiving updates again. The interests aim to solve race conditions too, no matter how early or late a view component flags itself as an interested party it will receive the last value that had been been notified -- similarly to bindings.

The example app is by no means a best practices of PureMVC - but is a quick example of why this utility can be VERY useful inside a PureMVC app, not only to reduce code redundancy, but for code cleanliness, and race conditions

Here is the test application

Here is the source

  • Author: nick
  • Published: Oct 23rd, 2009
  • Comments: 5

Flex - Regex restricted TextInput component

Tags: , ,

If you've ever used the `restrict` property on the Flex TextInput control - you've probably wished that it was more than just a string property. While it does allow you to specify characters, and character ranges like A-Z or 0-9, it isn't nearly as convenient or as robust as a regex.

Here is a simple subclass of TextInput that implements the same functionality as `restrict` but using a regular expression.

View the sample application ...and the source code.

 
package com.appdivision.components
{
    import flash.events.TextEvent;
    import mx.controls.TextInput;
 
    public class RegexTextInput extends TextInput
    {
 
        private var _regex:RegExp;
 
        public function RegexTextInput()
        {
            super();
        }
 
        [Bindable]
        public function set regex(value:RegExp):void
        {
            if (value != _regex)
            {
                _regex = value;
            }
        }
 
        public function get regex():RegExp
        {
            return _regex;
        }
 
        override protected function childrenCreated():void
        {
            super.childrenCreated()
 
            addEventListener(TextEvent.TEXT_INPUT, handleTextInput);
        }
 
        public function handleTextInput(event:TextEvent):void
        {
            if (regex)
            {
                 // What the text will be if this input is allowed to happen
                 var textToBe:String = "";
                // Accomidate for a selection
                if (selectionBeginIndex > 0)
                {
                    textToBe += text.substr(0, selectionBeginIndex)
                }
                textToBe += event.text;
                if (selectionEndIndex > 0)
                {
                    textToBe += text.substr(selectionEndIndex, text.length - selectionEndIndex);
                }
                var match:Object = regex.exec(textToBe);
                if (!match || match[0] != textToBe)
                {
                    // The textToBe didn't match the expression... stop the event
                    event.preventDefault();
                }
            }
        }
    }
}
 

Enjoy.