2010-02-17 5 views
2

org.as3commons.reflect를 사용하여 클래스 이름을 검색하고 런타임에 클래스를 인스턴스화 할 수 있습니다. 나는 또한 메소드를 호출하는 (작동하지 않는) 코드를 가지고있다. 그러나 실제로 속성 값을 설정하려고합니다. 속성이 내부적으로 Flex에서 메서드로 구현되는지 확실하지 않습니다.클래스를 동적으로 인스턴스화하고 런타임에 Flex 3에서 속성을 설정하는 방법은 무엇입니까?

나는 이름, 값 및 유형 (모두 문자열 임)의 세 가지 정보를 저장하는 Metadata 클래스가 있습니다. 나는 Array of Metadata 객체를 순환하여 인스턴스화 된 클래스에서 해당 속성을 설정할 수 있기를 원합니다.

 

var metadata:Array = new Array(); 

metadata[0] = new Metadata("type", "mx.controls.Text", null); 
metadata[1] = new Metadata("text", "Hello World!", null); 
metadata[2] = new Metadata("x", "77", null); 
metadata[3] = new Metadata("y", "593", null); 

this.addChild(new UIComponentBuilder().build(metadata)); 
 

나는 내가 인스턴스화, 또는 -inculde 컴파일러 지시문을 사용하는 것이었다 종류의 더미 변수를 선언해야한다는 인식 :

 

package com.acme.reporting.builders 
{ 
import com.acme.reporting.model.Metadata; 

import mx.core.UIComponent; 

import org.as3commons.reflect.ClassUtils; 
import org.as3commons.reflect.MethodInvoker; 

public class UIComponentBuilder implements IUIComponentBuilder 
{ 
    public function build(metadata:Array):UIComponent 
    { 
    var typeClass:Class = ClassUtils.forName(getTypeName(metadata)); 
    var result:* = ClassUtils.newInstance(typeClass); 

    for each (var m:Metadata in metadata) 
    { 
    if (m.name == "type") 
    continue; 

    // Attempting to invoke as method, 
       // would really like the property though 

    var methodInvoker:MethodInvoker = new MethodInvoker(); 

    methodInvoker.target = result; 
    methodInvoker.method = m.name; 
    methodInvoker.arguments = [m.value]; 

    var returnValue:* = methodInvoker.invoke(); // Fails! 
    } 

    return result; 
    } 

    private static function getTypeName(metadata:Array):String 
    { 
    if (metadata == null || metadata.length == 0) 
    throw new ArgumentError("metadata is null or empty"); 

    var typeName:String; 

    // Type is usually the first entry 
    if (metadata.length > 1 && metadata[0] != null && metadata[0].name == "type") 
    { 
    typeName = metadata[0].value; 
    } 
    else 
    { 
    var typeMetadata:Array = metadata.filter(
    function(element:*, index:int, arr:Array):Boolean 
    { 
     return element.name == "type"; 
    } 
    ); 

    if (typeMetadata == null || typeMetadata.length != 1) 
    throw new ArgumentError("type entry not found in metadata"); 

    typeName = typeMetadata[0].value; 
    } 

    if (typeName == null || typeName.length == 0) 
    throw new Error("typeName is null or blank"); 

    return typeName; 
    } 
} 
} 
 

는 여기에 몇 가지 사용 코드입니다. Flex의 불행한 단점.

또한 지금은 지정된 유형의 값을 유형을 지정하는 코드를 설명합니다.

답변

1

AS3의 동적 실행은 다른 언어보다 훨씬 간단합니다. 이 코드 :

var methodInvoker:MethodInvoker = new MethodInvoker(); 

methodInvoker.target = result; 
methodInvoker.method = m.name; 
methodInvoker.arguments = [m.value]; 

var returnValue:* = methodInvoker.invoke(); // Fails! 

이 단순화 될 수있다

var returnValue:* = result[method](m.value); 

편집 :

그것은, 그것은 다음과 같은 속성 할 것입니다 이후로 :

result[method] = m.value; 

반환 값이 없습니다 (음, getter를 다시 호출 할 수 있지만 setter/getter가 뭔가 이상하게 작동하지 않는 한 m.value을 반환하십시오.

+0

코드 및 MethodInvoker 종속성을 줄이는 데 유용합니다. 그러나, 나는 여전히 속성 값을 설정하기 때문에 내 경우에는 여전히 실패합니다. 예를 들어 위에서 지정한 샘플 메타 데이터를 사용하면 result [ "text"] ("Hello World!")와 같은 결과를 얻을 때 오류가 발생합니다. TypeError : Error # 1006 : value가 함수가 아닙니다. "text"속성에 해당하는 메서드가 없기 때문입니다. 속성을 사용하여 작업하게하는 방법에 대한 아이디어가 있습니까? 일부 언어와 같은 "setText"메서드가 있다고 생각하지 않습니다. 나는 틀릴 수 있었다. –

+0

@Edward Stembler, 당신은'result [method] = m.value;'시도 했습니까? 그것이 속성이라면 속성처럼 설정하십시오. –

+0

음, MethodInvoker 코드를 제거하고이를 var returnValue로 바꿨습니다 : * = result [m.name] (m.value); result [ "text"] ("Hello World!");와 같습니다. 메서드가 객체입니까, 아니면 문자열을 사용하여 메서드 또는 속성을 참조 할 수 있습니까? –

관련 문제