如何在 Flex 3 中创建双向数据绑定?

发布于 2024-08-12 08:09:36 字数 1317 浏览 6 评论 0原文

我需要将属性绑定到编辑控件,并让该控件将其值写回同一属性。问题是,我在创建控件之前设置源值:

<mx:Panel>
    <mx:Script>
        <![CDATA[
            [Bindable] public var editedDocument: XML;
        ]]>
    </mx:Script>
    <mx:TextInput id="docLabel" text="{editedDocument.@label}"/>
    <mx:Binding source="docLabel.text" destination="editedDocument.@label"/>
</mx:Panel>

我这样称呼它:

var xmlDoc: XML = <document label="some label" />;
var myPanel: MyPanel = new MyPanel();
myPanel.editedDocument = xmlDoc;
parent.addChild(myPanel);

发生的情况是这样的:

  • docLabel 文本字段最终变为空白(等于“”)
  • xmlDoc 的@label 属性设置为“”

想要是这样的:

  • docLabel 文本字段应包含“某个标签”,
  • xmlDoc 的 @label 属性应仅在 docLabel 的文本属性更改时更改。

如何使用 Flex 3 实现此目的?

编辑

我也尝试过这个:

<mx:Panel>
    <mx:Script>
        <![CDATA[
            [Bindable] public var editedDocument: XML;
        ]]>
    </mx:Script>
    <mx:TextInput id="docLabel"/>
    <mx:Binding source="editedDocument.@label" destination="docLabel.text"/>
    <mx:Binding source="docLabel.text" destination="editedDocument.@label"/>
</mx:Panel>

结果是一样的。

I need to bind a property to an edit control and have the control write its value back to the same property. The problem is, I'm setting the source value before the control is created:

<mx:Panel>
    <mx:Script>
        <![CDATA[
            [Bindable] public var editedDocument: XML;
        ]]>
    </mx:Script>
    <mx:TextInput id="docLabel" text="{editedDocument.@label}"/>
    <mx:Binding source="docLabel.text" destination="editedDocument.@label"/>
</mx:Panel>

I call this like so:

var xmlDoc: XML = <document label="some label" />;
var myPanel: MyPanel = new MyPanel();
myPanel.editedDocument = xmlDoc;
parent.addChild(myPanel);

What happens is this:

  • the docLabel text field ends up blank (equal to "")
  • the xmlDoc's @label attribute is set to ""

What I want is this:

  • the docLabel text field should contain "some label"
  • the xmlDoc's @label attribute should change only when the docLabel's text property changes.

How do I accomplish this, using Flex 3?

Edit

I have also tried this:

<mx:Panel>
    <mx:Script>
        <![CDATA[
            [Bindable] public var editedDocument: XML;
        ]]>
    </mx:Script>
    <mx:TextInput id="docLabel"/>
    <mx:Binding source="editedDocument.@label" destination="docLabel.text"/>
    <mx:Binding source="docLabel.text" destination="editedDocument.@label"/>
</mx:Panel>

The result is the same.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

黒涩兲箜 2024-08-19 08:09:36

您可以尝试在创建类后使用 BindingUtils 以编程方式创建绑定:
http://life.neophi.com/danielr/2007/03/programmatic_bindings。 html

我已经用它的许多变体来解决类似的问题。如果您无法从链接中弄清楚它,请发表评论,我将深入研究我的源代码,看看我能找到什么。

private function init():void 
{
  var xmlDoc: XML = <document label="some label" />;
  var myPanel: MyPanel = new MyPanel();
  myPanel.editedDocument = xmlDoc;
  parent.addChild(myPanel);
  BindingUtils.bindProperty(docLabel, "text", editedDocument, "label");

  //or maybe it should be one of these, I have not done binding to an XML attribute before
  BindingUtils.bindProperty(docLabel, "text", editedDocument, "@label");
  BindingUtils.bindProperty(docLabel, "text", editedDocument, "{@label}");
}

You can try using BindingUtils to programmatically create the binding after the class has been created:
http://life.neophi.com/danielr/2007/03/programmatic_bindings.html

There are many variations of this that I've used to tackle similar problems. If you can't figure it out from the link post a comment and I'll dig through my source code and see what I can find.

private function init():void 
{
  var xmlDoc: XML = <document label="some label" />;
  var myPanel: MyPanel = new MyPanel();
  myPanel.editedDocument = xmlDoc;
  parent.addChild(myPanel);
  BindingUtils.bindProperty(docLabel, "text", editedDocument, "label");

  //or maybe it should be one of these, I have not done binding to an XML attribute before
  BindingUtils.bindProperty(docLabel, "text", editedDocument, "@label");
  BindingUtils.bindProperty(docLabel, "text", editedDocument, "{@label}");
}
阳光的暖冬 2024-08-19 08:09:36

查看双向数据绑定
看一下正文部分:

在Flex 3中,如果你想设置
使用

的双向绑定

mx:绑定

您需要将其设置两次:
mx:绑定源=“a.property”目的地=“b.property”/>
mx:Binding source="b.property" target="a.property"/>

变为:

mx:Binding source="a.property" destination="b.property" twoWay="true"/>

Take a look at Two-way data binding.
Take a look at the part of the text:

In Flex 3, if you want to set
two-way binding using the

mx:Binding

tag you need to set it twice:
mx:Binding source="a.property" destination="b.property"/>
mx:Binding source="b.property" destination="a.property"/>

which becomes:

mx:Binding source="a.property" destination="b.property" twoWay="true"/>
痴者 2024-08-19 08:09:36

在 Flex 3 中,您最好这样做。还不确定是否可以直接绑定到 XML?

相反,做这样的事情:

        [Bindable] public var tmpString: String;


        public var onChange():void {
                tmpString = docLabel.text;
                //set the XML string, etc.
        }

    ]]>
</mx:Script>
<mx:TextInput id="docLabel" text="{tmpString}" change="onChange()" />

In Flex 3 you would be better of doing something like this. Also not sure you can bind directly to XML?

Instead do something like this:

        [Bindable] public var tmpString: String;


        public var onChange():void {
                tmpString = docLabel.text;
                //set the XML string, etc.
        }

    ]]>
</mx:Script>
<mx:TextInput id="docLabel" text="{tmpString}" change="onChange()" />

风吹短裙飘 2024-08-19 08:09:36

我认为双向数据绑定是 Flex 4 中的一个新功能。

I think bidirectional data binding is a new feature in Flex 4.

秋日私语 2024-08-19 08:09:36

这直接来自 Adboe http://opensource.adobe.com /wiki/display/flexsdk/Two-way+Data+Binding,而且它也是 Flex 3!

This is straight from Adboe http://opensource.adobe.com/wiki/display/flexsdk/Two-way+Data+Binding, and it's Flex 3 too!

¢好甜 2024-08-19 08:09:36

我创建了自定义控件,当给定一个提供程序对象时,该控件以编程方式创建双向绑定,该提供程序对象具有名称与控件 ID 匹配的合适属性。以下是 TextInput 的示例:

public class BoundTextInput extends TextInput
{
  // some code omitted for brevity:
  // Create getter / setter pair, call invalidateProperties()
  // and set internal flag for efficiency

  // create bindings in commitProperties:
  override protected function commitProperties():void
  {
    if (this._fProviderChanged) {
      this._fProviderChanged = false;
      if (null != this._provider && this._provider.hasOwnProperty(this.id) && this._provider[this.id] is String) {
        // this is the core bit
        BindingUtils.bindProperty(this, "text", this._provider, this.id);
        BindingUtils.bindProperty(this._provider, this.id, this, "text");
      }
    }
    // Normally, you call the overridden method first,
    // but we want to see the values initialized by the new
    // binding right away, so we first create the bindings
    // and then commit all inherited properties
    super.commitProperties();
}

}

这是我如何在其他组件之一(弹出对话框)中使用它的示例。 data 属性设置为适当模型类的实例,该实例始终是一个哑的[Bindable] 容器。

<?xml version="1.0" encoding="utf-8"?>
<PopUp xmlns="com.econemon.suite.gui.components.*" xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Form width="100%" height="100%" >
    <mx:FormHeading label="Server-URL" />
    <mx:FormItem label="URL" >
      <!--
        If it is available, and of type String, data.urlServer
        is bound to the text property of this TextInput
      -->
      <BoundTextInput id="urlServer" provider="{this.data}"/>
    </mx:FormItem>
    <mx:FormItem>
      <mx:Button label="OK" click="this.submit(event)" />
    </mx:FormItem>
  </mx:Form>
</PopUp>

I created custom controls that programmatically create two-way bindings when given a provider object that has a suitable property whose name matches the control's id. Here's an example for a TextInput:

public class BoundTextInput extends TextInput
{
  // some code omitted for brevity:
  // Create getter / setter pair, call invalidateProperties()
  // and set internal flag for efficiency

  // create bindings in commitProperties:
  override protected function commitProperties():void
  {
    if (this._fProviderChanged) {
      this._fProviderChanged = false;
      if (null != this._provider && this._provider.hasOwnProperty(this.id) && this._provider[this.id] is String) {
        // this is the core bit
        BindingUtils.bindProperty(this, "text", this._provider, this.id);
        BindingUtils.bindProperty(this._provider, this.id, this, "text");
      }
    }
    // Normally, you call the overridden method first,
    // but we want to see the values initialized by the new
    // binding right away, so we first create the bindings
    // and then commit all inherited properties
    super.commitProperties();
}

}

This is an example of how I use it inside one of my other components (a popup dialog). The data property is set to an instance of the appropriate model class, which is always a dumb, [Bindable] container.

<?xml version="1.0" encoding="utf-8"?>
<PopUp xmlns="com.econemon.suite.gui.components.*" xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Form width="100%" height="100%" >
    <mx:FormHeading label="Server-URL" />
    <mx:FormItem label="URL" >
      <!--
        If it is available, and of type String, data.urlServer
        is bound to the text property of this TextInput
      -->
      <BoundTextInput id="urlServer" provider="{this.data}"/>
    </mx:FormItem>
    <mx:FormItem>
      <mx:Button label="OK" click="this.submit(event)" />
    </mx:FormItem>
  </mx:Form>
</PopUp>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文