Flex 경고 : 클래스 '객체'에서 'foo'에 속성에 묶을 수 없음 (클래스는 ieventDispatcher가 아닙니다)

StackOverflow https://stackoverflow.com/questions/928081

문제

폼 요소에 바인딩하려는 12 개 정도의 필드가 포함 된 객체가있어 해당 객체를 사용하여 저장할 서버로 다시 데이터를 보낼 수 있습니다.

내 컨테이너 개체의 정의 :

private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:Object = emptyLink;

currentLink 런타임에 ArrayCollection에서 특정 인덱스에 할당됩니다. emptyLink 초기화 목적을위한 개체.

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
    <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
        <mx:TextInput id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" />
        <mx:TextInput id="trigger2" width="100%" textAlign="left" text="{currentLink.trigger2}" />
        <mx:TextInput id="trigger3" width="100%" textAlign="left" text="{currentLink.trigger3}" />
        <mx:TextInput id="trigger4" width="100%" textAlign="left" text="{currentLink.trigger4}" />
        <mx:TextInput id="trigger5" width="100%" textAlign="left" text="{currentLink.trigger5}" />
    </mx:VBox>
</mx:Panel>

물론 이것은 컴파일하고 표시하지만 각 인스턴스에 대한 런타임 경고가 있습니다.

경고 : 클래스 '객체'에서 'trigger1' '에 묶을 수 없음 (클래스는 ieventDispatcher가 아닙니다) 경고 : 클래스'객체에서 'trigger2'에 묶을 수 없음 (클래스는 ieventDispatcher가 아닙니다) 경고 : 바인딩 할 수 없습니다. 속성 'trigger3'에서 'class'Object '(클래스는 ieventDispatcher가 아닙니다) 경고 : 클래스'객체 '에서'trigger4 '에 묶을 수 없음 (클래스는 ieventDispatcher가 아닙니다) 경고 : 클래스에서'trigger5 '에 바인딩 할 수 없습니다. 'Object'(클래스는 ieventDispatcher가 아닙니다)

그리고 currentLink 객체가 업데이트되지 않습니다 TextInput 필드가 변경되었습니다.

명백한 대답은 내 객체가 구현되는 클래스의 인스턴스가되어야한다는 것입니다. IEventDispatcher. 그 대답은 나에게 말하는 것은 그 인터페이스를 구현하는 것의 세부 사항입니다 (필요하지 않은 것은 무엇입니까? 바인딩의 경우 인터페이스 구현의 세부 사항에 대해 걱정할 필요가 없습니다.

그러한 수업이 존재합니까? 그렇지 않다면이 작업을 수행하기위한 최소 및/또는 허용 표준은 무엇입니까?

도움이 되었습니까?

해결책

객체 프록시를 사용해야합니다 (Chetan이 언급 한대로) - valuecommit을 사용하여 입력에 입력 한 텍스트를 객체에 다시 가져와야합니다.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.utils.ObjectProxy;
              private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);


private function handleClick():void
{
    trace(currentLink.trigger1);
}
]]>
</mx:Script>

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
        <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
                <mx:TextInput  id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" valueCommit="{currentLink.trigger1 = trigger1.text;}"/>

                <mx:Button label="Click" click="handleClick()"/>
        </mx:VBox>
</mx:Panel>        

</mx:WindowedApplication>

다른 팁

Object 이벤트를 파견하지 않습니다. 변수 바인드 가능성을 만들었지 만 변수에 의해 참조 된 객체의 특성 currentLink 구속 될 수 없습니다.

사용 ObjectProxy 대신에.

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);

가장 먼저 알고 싶은 것은 Flex 3의 바인딩이 양방향이 아니라는 것입니다. 바인딩 발현은 바인딩 발현 (currentLink.trigger1)의 소스가 대상 (TextInput)이 변경 알림을 받고 그에 따라 업데이트 할 수 있도록 변경하는 경우를 보장합니다. 바인딩이 다른 방향으로 가기를 원한다면이 작업을 수행하는 두 가지 이상이 있습니다.

  1. MX : 바인딩 태그를 사용하여 TextInput.text를 개체로 다시 사용하십시오.
  2. Bindingutils를 사용하여 프로그래밍 방식 으로이 작업을 수행하십시오.

Flex 4에서는 양방향 바인딩 @{some.binding.expression}에 대한 새로운 구문을 도입하고 있지만 Flex 3에서는 사용할 수 없습니다.

두 번째 부분에서 : 당신이 받고있는 오류는 "일반적인"프로토 타입 객체에 바인딩하기 때문입니다. [bindable] 메타 데이터 태그를 속성 또는 클래스에 적용 할 때 MXMLC 컴파일러는 바인딩 유틸리티 사용 및 속성 변경 감시자를 포함하는 코드로 생성됩니다. 그러나 프로토 타입 객체가 내장 된 것이기 때문에이 작업을 수행 할 수 없습니다. 바인딩 가능한 사용자 정의 액션 스크립트 클래스를 만들 수 있습니다 (또는 특정 속성을 바인딩 할 수 있음). MXMLC 컴파일러는 ieventDispatcher를 구현하는 클래스를 생성하므로 바인딩을 지원합니다. 이는 프로토 타입 개체보다 빠른 이점이 있으며 컴파일 타임 확인을 제공합니다. 즉, 유효하지 않은 속성을 참조하면 컴파일러 오류를 받게됩니다.

다른 대안은 회원이 제안한 다른 하나와 같이 프로토 타입을 ObjectProxy로 마무리하는 것입니다.

더 큰 프로젝트에서 불쾌한 코드를 찾는 방법에 대한 팁 - 둘에 중단 점을 넣으십시오.

trace("warning: unable to bind to property '"

SDK의 PropertyWatcher 클래스 (Navigate> Open Type> ...)의 라인. 그런 다음 StackTrace는 깨진 바인딩을 보유하는 UI 구성 요소를 찾는 데 도움이됩니다.

일반적으로 "수업에서 Foo에 구속 할 수없는 이유는 왜냐하면 당신은 foo를 위해 getter 또는 setter를 놓치고 있습니다.. 너 ~할 수 있었다 또한 Foo를 공개 변수로 범위로 만들었습니다 (캡슐화를 중단하더라도)

그래서 당신은 그것을 사라지려면이 두 가지 모두가 필요합니다.

public function set foo (o:FooObject) : void {
...
}

또는

public function get foo() : FooObject {
...
}

Livedocs 참조는 다음과 같습니다 인터페이스를 위해. 그것은 분명 할 것입니다.

인용 :

일반적으로 사용자 정의 클래스가 이벤트 파견 기능을 얻는 가장 쉬운 방법은 EventDispatcher를 확장하는 것입니다.

따라서,

Private STATIC CONSTILLINK : EventDisPatcher = {

Flex를 오랫동안 사용하지 않았으므로 요구 사항에 맞지 않지만 XML을 사용하지 않는 이유는 무엇입니까? XML의 텍스트 텍스트 값을 속성으로 설정할 수 있다고 생각합니다.

의사 코드를 사용하고 있지만 이와 같은 것은 나에게 의미가 있습니다.

[Bindable] private static const currentLink:XML = <root>
                                                    <trigger1 value=""/>
                                                    <trigger2 value="" />
                                                  </root>;
...
<mx:TextInput id="trigger1" width ... text="{currentLink.trigger1.@value}" />

아마도 이런거?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top