What does [Bindable] mean in actionscript? - actionscript

[Bindable]
/**
* Display output of video device.
*/
public var videoLocal : Video;
Anyone knows?

[Bindable] is a one of several meta tags that you can use in flex ActionScript code. It can be applied to properties, or methods that are marked in any scope. It cannot be used with static class members.
The key to using the [Bindable] meta tag is understanding what is going on under the hood when you use it. Essentially using data binding is a type of shorthand for adding event listeners and dispatching events.
There are two basic forms of the [Bindable] tag. The first is just [Bindable] followed by a var/property declaration. The Second is [Bindable(event="eventname")] followed by either a var/property declaration, a function/method declaration or one half of a getter/setter declaration.
I'll explain the longer notation first since the other builds on the same concept but with even more shorthand.
When you use [Bindable(event="eventname")] you are essentially telling the compiler that this var/property/function/method (call this the instance member) is 'available' to be used as the source for data binding. You are also telling it that when the value of the instance member has been invalidated/changed and it needs to be re-read that the "eventname" event will be dispatched.
In this longer form this all you are doing. You the developer are responsible for actually dispatching the "eventname" event whenever the value needs to be updated in the binding subscribers.
The real efficiency of using data binding comes on the subscribing side. The typical notation you will see in MXML is value="{instance.propertyName}" When you use the notation { } you are telling the compiler to do the following:
Create an event listener that listens to the event named in the bindable meta tag
In that event listener re-read the instance.propertyName and update this value
If you use the shorter form [Bindable], and you add the tag before a property/var, the compiler fills in the blanks and adds some additional functionality to make the property bindable. Essentially you are telling the compiler "add the events and methods you need to make this property bindable"
Now the way to think of what the compiler will do under the hood is this.
make a private version of your var
create an "event" to trigger the binding
create a getter function with scope and name of your original var that returns the private verson of the var when called.
create a setter function with scope and name of your original var that sets the private version of the var when called AND dispatches the triggering event.
In essence the compiler will do much of the work for you.
[Bindable]
public var xyz
is equivalent to
private var _xyz:String;
[Bindable(event="updateXYZValue")]
public function get xyz():String{
return _xyz;
}
public function set xyz(newxyz:String):void{
_xyz = newxyz;
dispatchEvent(new Event("updateXYZValue"));
}
The only functional differences in these is that in the first instance;
you do not know the name of the event that will be dispatched to trigger the binding
there is no way to update the underlying value without triggering the data binding
This second example also demonstrates one special case of the [Bindable] meta tag. This is that when you are applying it to a getter/setter pair defined for the same variable name you need only apply it to one or the other, it will apply to both. Typically you should set it on the getter.
You can use either notation on a function/method however if you do not specify an event the binding will never be triggered so if you are trying to bind to a function you should alway specify an event. It is also possible to specify more than one triggering event by stacking the tag. eg.
[Bindable(event="metaDataChanged")]
[Bindable(event="metaObjectUpdated")]
public function readMyMetaData():MetaDataObject{
var myMetaDataObject:MetaDataObject;
.
.
.
return myMetaDataObject;
}
This would presume that somewhere else you your class you will dispatch this metaDataChanged event or the metaObjectUpdated event when you want trigger the binding.
Also note that with this notation you can tie the binding of any instance member to any event that the instance will dispatch. Even inherited events that you yourself do not generate such as FrameEnter, OnChange, etc...
Data bindings can also be setup and destroyed during runtime. If you are interested in this take a look at the mx.binding.utils classes.

It is used in Databinding with Flex, you can read more about it here
http://livedocs.adobe.com/flex/3/html/help.html?content=databinding_2.html
Creating properties to use as the source for data binding
When you create a property that you
want to use as the source of a data
binding expression, Flex can
automatically copy the value of the
source property to any destination
property when the source property
changes. To signal to Flex to perform
the copy, you must use the [Bindable]
data tag to register the property with
Flex.

As an addition to what Justin said, you can actually use two ways data binding in Flex with the # character. Here's an example:
<s:TextInput id="txt1" text="#{txt2.text}" />
For a working example with source code enabled you can check out this article I wrote a while back:
Two-ways data binding in Flex

Related

Aurelia: notification when ANY property is modified

Do you see any way to know when ANY model’s property has been modified through a binding?
I would need something generic because it would be applied to all the forms of the application. This means I cannot just have a 'property’Changed() observable callback for every properties of the models. I’m thinking along the ways of overriding the properties setters created by the binding engine so they can call a single defined callback but I feel like there could be a better way.
I created a aurelia-plugin for this kind of scenario (and more).
Its not exactly what your asking for, but can help you a lot.
because the plugin will create a single property called isDirty that you can observe and fire your code accordingly.
https://github.com/avrahamcool/aleph1-aurelia-utilities
look at the Dirty Tracking a model: section
your model class need to extends the baseClass provided by the plugin.
now you can decorate any properties of your model with the
#dirtyTrack() decorator.
for babel users: the assignment in the declaration will set the
default value for the property. for TS users: you should call the
decorator with a parameter #dirtyTrack(7) someInt: number;
this will set up a isDirty variable in your model. this property will
be automatically updated to with every change to your tracked
properties.
at any point, you can call saveChanges() on your model, to commit the
current changes. or discardChanges() to revert back to the last saved
point. you can call serialize() to get a pojo object from your model,
or deserialize(pojo) to populate your model from a pojo object.
Ok, I ended up just using the binding engine to watch all properties changes. This allowed me to implement my isDirty checks without modifying the existing models...
So the final code looks like this:
Object.getOwnPropertyNames(obj).forEach(p => {
this.subscriptions.push(this.binding.propertyObserver(obj, p)
.subscribe(() => this.updateDirty()));
});
my updateDirty() method is called after every property change and no change was necessary to the model.
If anyone can come up with a better solution, I'm still interested but this fits my needs for the time being.

Creating a listener on a list for changes

I have a dart object which contains a list. Simply put:
class Test extends PolymerElement{
List list = [];
addTask(item){
list.add(item);
}
}
and I wanted to implement a listener on that list in another object:
class listenerClass extends PolymerElement {
Test get _data => $['Object'];
}
So the object is retrieved from the dom withthe getter.
Is there a way to observe a change in the parent? I tried the following:
#Observe("_data.list")
dataListChanged(_,__){
var item = _data.list.last;
//do magic with item.
}
I have the underscore because it is private and isnt exposed to Dom or anything... but the list itself isnt a property so it doesnt notify or anything.
I was hoping there was a way to do some sort of listener for it though.
My desired endstate is that I want to fire a function in the parent whenever an item is added to the list, with only the reference to the child object as defined above. Even though this _data is populated by way of Polymer, Since this isnt touching properties at all, the answer may likely just be Pure dart.
This is not how polymer works. Polymer framework has no way to know you have defined a getter in your class and emit the right notification.
You should add notify to the list property of Test and bind that to a property in listenerClass. Then observe that variable.
But probably you will have better luck with ObservableList and using autonotify for a simpler way to use observability with polymer-dart projects.

Notify Observable-Watchers programmatically in Dart

Once again, a Dart/Polymer related question.
I wanted to use the Parse.com JavaScript library, but since it's not available in Dart I've written Wrapper classes which store a JsObject and delegate all calls from Dart to the corresponding JavaScript object. Basically it's like a proxy.
Guess what, it works pretty great.
However, my observables don't. To understand this, you have to take a look at the following structure of one of my "proxy"-classes.
class ParseObject extends Observable {
JsObject _jsDelegate = new JsObject(context['Parse']['ParseObject']);
void set(String key, dynamic value) {
_jsDelegate.callMethod('set', [key, jsify(value)];
}
dynamic get(String key) {
return dartify(_jsDelegate.callMethod('get', [key]));
}
}
The HTML code of my Polymer Element looks like this:
<div>Name: {{project.get('name')}}</div>
Since the data binding is only evaluate in case the parameter of the method changed, it will never be updated and thus even though the name is changed, the old one will stay in place.
The solution I came up with is to store all the values the user is setting in the ParseObject#set(String, dynamic) method into a Map which is observable. This works but I think it's quiete dirty since I have to make sure that both Maps, the one in Dart and the one in the ParseObject's JavaScript representation equal.
Thus I am looking for a better solution and I think of some kind of method to tell Polymer to reevaluate it's data bindings.
Does such a method exist or are there any other possibilities to address this problem?
Extending observable by itself does nothing yet.
You need to annotate the getters with #observable (and if you are not using Polymer, you also need to add the observable transformer to pubspec.yaml). You can't make functions observable (this works in Polymer elements but not in Observable model classes. For more details about observable see for example Implement an Observer pattern in Dart or Dart: #observable of getters

Delphi - Accessing Object Instance Data from Another Object

I have my main form. Form_Main
It creates two instances of two classes.
Candle_Data : TCandle_Data;
Indicator_2700 : TIndicator_2700;
In order for Indicator_2700 to properly compute its values it must have access to the candle data in the obect Candle_Data from inside one of its methods. Thus how can Indicator_2700 access data inside Candle_Data? Does Form_Main have to pass it as a argument at Constructor time?
Both Class declarations are in their own unit file.
You could use any of the following (non-exhaustive) methods:
Pass the object reference as a parameter to any methods that need it. Of course you need to get hold of Candle_Data so the suitability of this approach really depends who the caller is.
Pass the Candle_Data object reference to the constructor of the other object and then store it in a private member field.
Make the object reference a public property of the single instance of the main form and access it that way.
We don't really have enough information to advise you which is best but the starting point is always to prefer parameters and local variables over global state.
TIndicator_2700 could have a property to link it to the instance of TCandle_Data that is relevant to its own instance or you should supply it as an argument to the method that needs to access the data.
You could certainly pass the TCandle_Data instance into the constructor of Indicator_2700, and store a reference within the resulting instance until you needed it.
Both class declarations are in their own unit file.
That suggests that both have nothing to do with the other. But still you want one to have knowledge about the other. It sounds like a little design mixup, but that doesn't need to be the case.
There are multiple solutions, here are three of them, each with its own purpose:
Place both classes in the same unit, only if both classes have a common theme/subject (e.g. TCar and TAirplane in the unit Transport),
Use one unit in the other unit, only if both units represent different subjects, but one may depend on the other (e.g. unit Transport uses unit Fuel: TCar needs TDiesel, but TDiesel doesn't need a TCar). This only works one-way. Delphi prevents using in both ways with a compiler error: "Circular unit reference to 'Fuel'". The only workaround is to use the second unit in the implementation section, but that usually is considered a big nono.
Declare a new base-class in a new unit, only if the base-class has a common subject, but the final descendants do not (e.g. TFuel is used by all transportation classes like TCar, TAirplane and THorse, but TFood (a descendant of TFuel) is only used by THorse and TPerson).
As for how to link both classes together, see the already given answers.

F# IEvent.create

Where is it gone ?
let triggerFindNext,findNextEvent = IEvent.create<EventArgs>()
The field, constructor or member 'create' is not defined
maybe I must to add some Framework for it ?
The IEvent.create function has been deprecated. A new way of creating events is to create instance of the Event type. In the simplest case you can write just this:
let evt = new Event<EventArgs>()
// Trigger event (instead of first element of the tuple)
evt.Trigger()
// Returns IEvent<EventArgs> value (instead of second element of the tuple)
evt.Publish
This represents event using IEvent<_> value (and doesn't generate .NET compatible event if you expose it as a property) and it uses generic Handler<_> delegate from F# libraries.
(If you want to generate .NET compatible event usable from C# then you need to add CLIEvent attribute and you can use variant of Event that takes delegate as generic parameter as described in the answer already mentioned by others)
EDIT: I posted a more complete F# snippet (with nicer formatting) here: http://fssnip.net/1d

Resources