문제

지금까지는 약간의 Flex 개발만 수행했지만 mxml 파일보다 프로그래밍 방식으로 컨트롤을 만드는 접근 방식을 선호했습니다. 제발, 내가 틀렸다면 정정해 주십시오!) 두 가지 방법을 모두 사용할 수는 없다는 것을 알아냈습니다. 즉, 클래스 기능은 별도의 ActionScript 클래스 파일에 있지만 포함된 요소는 mxml에 선언되어 있습니다.

생산성 측면에서는 큰 차이가 없는 것 같지만 프로그래밍 방식으로 데이터 바인딩을 수행하는 것은 다소 사소한 일처럼 보입니다.mxml 컴파일러가 데이터 바인딩 표현식을 변환하는 방법을 살펴보았습니다.그 결과 생성된 콜백이 많아지고 mxml 표현보다 훨씬 많은 행이 생성됩니다.질문은 다음과 같습니다. 상처를 주지 않고 프로그래밍 방식으로 데이터 바인딩을 수행할 수 있는 방법이 있습니까?

도움이 되었습니까?

해결책

MXML을 두려워하지 마십시오.뷰를 배치하는 데 좋습니다.직접 작성하시면 재사용 가능 구성 요소를 ActionScript로 작성하면 때로는 좀 더 제어할 수 있지만 재사용할 수 없는 뷰의 경우 MXML이 훨씬 더 좋습니다.더 간결하고 바인딩 설정이 매우 쉽습니다.

그러나 순수 ActionScript의 바인딩은 그리 어렵지 않습니다.많은 작업이 수행되는 MXML만큼 간단하지는 않지만 큰 노력을 들이지 않고도 수행할 수 있습니다.

당신이 가지고 있는 것은 BindingUtils 그리고 그것은 방법이다 bindSetter 그리고 bindProperty.나는 주로 일을 하거나 전화를 하고 싶기 때문에 거의 항상 전자를 사용합니다. invalidateProperties 값이 변경되면 속성만 설정하고 싶지는 않습니다.

당신이 알아야 할 것은 이 두 개가 다음 유형의 객체를 반환한다는 것입니다. ChangeWatcher, 어떤 이유로 바인딩을 제거하려면 이 개체를 잡고 있어야 합니다.이것이 ActionScript의 수동 바인딩이 MXML의 바인딩보다 약간 덜 편리하게 만드는 이유입니다.

간단한 예부터 시작해 보겠습니다.

BindingUtils.bindSetter(nameChanged, selectedEmployee, "name");

이는 메소드를 호출하는 바인딩을 설정합니다. nameChangedname 변수의 객체에 대한 속성 selectedEmployee 변화.그만큼 nameChanged 메소드는 새로운 값을 수신합니다. name 속성을 인수로 사용하므로 다음과 같아야 합니다.

private function nameChanged( newName : String ) : void 

이 간단한 예제의 문제점은 일단 이 바인딩을 설정하면 지정된 개체의 속성이 변경될 때마다 실행된다는 것입니다.변수의 값 selectedEmployee 변경될 수 있지만 변수가 이전에 가리킨 객체에 대한 바인딩은 여전히 ​​설정되어 있습니다.

이 문제를 해결하는 방법에는 두 가지가 있습니다.유지하거나 ChangeWatcher 에 의해 반환됨 BindingUtils.bindSetter 주변에 전화하고 unwatch 바인딩을 제거하고 싶거나(대신 새 바인딩을 설정하고 싶을 때), 자신에게 바인딩하고 싶을 때 사용하세요.첫 번째 옵션을 먼저 보여주고 나서 자신에게 바인딩한다는 것이 무엇을 의미하는지 설명하겠습니다.

그만큼 currentEmployee getter/setter 쌍으로 만들어 다음과 같이 구현할 수 있습니다(setter만 표시).

public function set currentEmployee( employee : Employee ) : void {
    if ( _currentEmployee != employee ) {
        if ( _currentEmployee != null ) {
            currentEmployeeNameCW.unwatch();
        }

        _currentEmployee = employee;

        if ( _currentEmployee != null ) {
            currentEmployeeNameCW = BindingUtils.bindSetter(currentEmployeeNameChanged, _currentEmployee, "name");
        }
    }
}

무슨 일이 일어나는가? currentEmployee 속성이 설정되면 이전 값이 있는지 확인하고, 그렇다면 해당 객체에 대한 바인딩을 제거합니다(currentEmployeeNameCW.unwatch()) 그런 다음 개인 변수를 설정하고 새 값이 null 에 대한 새 바인딩을 설정합니다. name 재산.가장 중요한 것은 ChangeWatcher 바인딩 호출에 의해 반환됩니다.

이것은 기본 바인딩 패턴이며 잘 작동한다고 생각합니다.하지만 이를 좀 더 간단하게 만드는 데 사용할 수 있는 트릭이 있습니다.대신 자신에게 바인딩할 수 있습니다.매번 바인딩을 설정하고 제거하는 대신 currentEmployee 속성을 변경하면 바인딩 시스템이 이를 수행하도록 할 수 있습니다.당신의 creationComplete 핸들러(또는 생성자 또는 적어도 어느 정도 일찍) 다음과 같이 바인딩을 설정할 수 있습니다.

BindingUtils.bindSetter(currentEmployeeNameChanged, this, ["currentEmployee", "name"]);

이는 바인딩뿐만 아니라 currentEmployee 재산 this, 뿐만 아니라 name 이 개체의 속성입니다.따라서 언제든지 방법을 변경하면 currentEmployeeNameChanged 호출됩니다.저장할 필요가 없습니다. ChangeWatcher 바인딩을 제거할 필요가 없기 때문입니다.

두 번째 해결책은 많은 경우에 작동하지만, 특히 뷰가 아닌 클래스에서 바인딩 작업을 할 때 첫 번째 방법이 때때로 필요하다는 것을 발견했습니다. this 이벤트 발송자여야 하며 currentEmployee 작동하려면 바인딩 가능해야 합니다.)

다른 팁

오늘부터 존재합니다.:)

방금 ActionScript 데이터 바인딩 프로젝트를 오픈 소스로 출시했습니다. http://code.google.com/p/bindage-tools

BindageTools는 파이프라인 스타일로 데이터 바인딩을 선언하는 유창한 API를 사용하는 BindingUtils(여기서 단어 놀이 참조)의 대안입니다.

Bind.fromProperty(person, "firstName")
    .toProperty(firstNameInput, "text");

양방향 바인딩:

Bind.twoWay(
    Bind.fromProperty(person, "firstName"),
    Bind.fromProperty(firstNameInput, "text"));

명시적 데이터 변환 및 검증:

Bind.twoWay(
    Bind.fromProperty(person, "age")
        .convert(valueToString()),
    Bind.fromProperty(ageInput, "text")
        .validate(isNumeric()) // (Hamcrest-as3 matcher)
        .convert(toNumber()));

등.사이트에 더 많은 예제가 있습니다.다른 기능도 많이 있습니다. 한 번 살펴보세요.--매튜

편집하다:업데이트된 API

구성 요소의 MXML과 ActionScript를 별도의 파일로 분리하는 한 가지 방법은 ASP.Net 1.x 코드 숨김 모델과 유사한 작업을 수행하는 것입니다.이 모델에서 선언 부분(이 경우 MXML)은 명령 부분(ActionScript)의 하위 클래스입니다.따라서 클래스에 대한 코드 숨김을 다음과 같이 선언할 수 있습니다.

package CustomComponents
{
    import mx.containers.*;
    import mx.controls.*;
    import flash.events.Event;

    public class MyCanvasCode extends Canvas
    {
        public var myLabel : Label;

        protected function onInitialize(event : Event):void
        {
            MyLabel.text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
        }
    }
}

...그리고 마크업은 다음과 같습니다:

<?xml version="1.0" encoding="utf-8"?>
<MyCanvasCode xmlns="CustomComponents.*" 
    xmlns:mx="http://www.adobe.com/2006/mxml"
    initialize="onInitialize(event)">
    <mx:Label id="myLabel"/>    
</MyCanvasCode>

이 예에서 볼 수 있듯이 이 접근 방식의 단점은 다음과 같은 컨트롤을 선언해야 한다는 것입니다. myLabel 두 파일 모두에서.

mxml과 액션 스크립트를 함께 사용하는 데 일반적으로 사용하는 방법이 있습니다.내 모든 mxml 구성 요소는 더 복잡한 코드를 추가하는 작업 스크립트 클래스에서 상속됩니다.그런 다음 mxml 파일에서 이 클래스에 구현된 이벤트 리스너를 참조할 수 있습니다.

문안 인사,

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