1

Is it possible to specify MXML-esque "binding strings" in ActionScript?

For example, I want to be able to do something like:

MXMLBinding(this, "first_item",
            this, "{myArrayCollection.getItemAt(0)");
MXMLBinding(this, ["nameLbl", "text"],
            this, "Name: {somePerson.first} {somePerson.last}");

Edit: thanks for the responses and suggestions… Basically, it seems like you can't do this. I've dug around and figured out why.

6 Answers 6

2

(Shameless plug)

BindageTools can do this:

Bind.fromProperty(this, "myArrayCollection", itemAt(0))
    .toProperty(this, "first_item");

Bind.fromAll(
    Bind.fromProperty(this, "somePerson.first"),
    Bind.fromProperty(this, "somePerson.last")
    )
    .format("Name: {0} {1}")
    .toProperty(this, "nameLbl.text");

Note that BindageTools puts the source object first and the destination last (whereas BindingUtils puts the destination first and the source last).

Sign up to request clarification or add additional context in comments.

Comments

0

Using ChangeWatcher (e.g., via BindingUtils.bindProperty or .bindSetter) is the way to go, yes. I admit it's a strange notation, but once you get used to it, it makes sense, works perfectly and is quite flexible, too.

Of course, you could always wrap those functions yourself somehow, if the notation bugged you -- both methods are static, so doing so in a way that feels more appropriate to your application should be a fairly straightforward exercise.

2 Comments

It's not so much that the notation is strange… It's that it takes a whole lot more code, which is a whole lot more verbose, to accomplish exactly the same thing.
Yeah, I just don't think there's another way, actually.
0

I could use BindingUtils or ChainWatcher, but then I'd end up with code that looks something like this:

…
    BindingUtils.bindSetter(updateName, this, ["somePerson", "first"]);
    BindingUtils.bindSetter(updateName, this, ["somePerson", "last"]);
…
protected function updateName(...ignored):void {
    this.nameLbl.text = "Name: " + somePerson.first + " " + somePerson.last;
}

Which is just a little bit ugly… And the first example, binding to arrayCollection.getItemAt(0), is even worse.

1 Comment

Curly brace {} binding is specific to MXML, and is not available in pure AS3. BindingUtils is the way to go.
0

Does the first parameter (function) of BindingUtils.bindSetter method accept anonymous methods?

BindingUtils.bindSetter(function()
  {
    this.nameLbl.text = "Name: " + somePerson.first + " " + somePerson.last;
  }, this, ["somePerson", "last"]);

I hate anonymous methods and obviously it's even more uglier - so I won't recommend that even if it works, but just wondering if it works.

Comments

0

Never the answer anyone wants to hear, but just manage this stuff with getters/setters in ActionScript. With a proper MVC, it's dead simple to manually set your display fields.

public function set myArrayCollection(value:Array):void {
  myAC = new ArrayCollection(value);
  first_item = mcAC.getItemAt(0);  // or value[0];
}

etc....

2 Comments

The difficulty, though, is this won't bind to myAC[0]… To do that, I've got to add a ChangeListener, to myAC, and… (well, you know the rest of that story).
I guess my point is that programmers have been managing without binding for a long time. Usually a good architecture is sufficient. You might need a notification system where you can react to changes inside your AC.
0

Alright, so I've done some digging, and here's what's up.

Bindings in MXML are, contrary to reason, setup by Java code (modules/compiler/src/java/flex2/compiler/as3/binding/DataBindingFirstPassEvaluator.java, if I'm not mistaken) at compile time.

For example, the binding: first_item="{myArrayCollection.getItemAt(0)}"` is expanded into, among other things, this:

    // writeWatcher id=0 shouldWriteSelf=true class=flex2.compiler.as3.binding.PropertyWatcher shouldWriteChildren=true
    watchers[0] = new mx.binding.PropertyWatcher("foo",
                                                 { propertyChange: true }, // writeWatcherListeners id=0 size=1
                                                 [ bindings[0] ],
                                                 propertyGetter);

    // writeWatcher id=1 shouldWriteSelf=true class=flex2.compiler.as3.binding.FunctionReturnWatcher shouldWriteChildren=true
    watchers[1] = new mx.binding.FunctionReturnWatcher("getItemAt",
                                                       target,
                                                       function():Array { return [ 0 ]; },
                                                       { collectionChange: true }, 
                                                       [bindings[0]],
                                                       null);

    // writeWatcherBottom id=0 shouldWriteSelf=true class=flex2.compiler.as3.binding.PropertyWatcher
    watchers[0].updateParent(target);

    // writeWatcherBottom id=1 shouldWriteSelf=true class=flex2.compiler.as3.binding.FunctionReturnWatcher
    // writeEvaluationWatcherPart 1 0 parentWatcher
    watchers[1].parentWatcher = watchers[0];
    watchers[0].addChild(watchers[1]);

This means that it is simply impossible to setup curly-brace MXML-style bindings at runtime because the code to do it does not exist in ActionScript.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.