2009-05-29 26 views
22

Tôi có một đối tượng chứa hàng tá trường tôi muốn liên kết với các thành phần biểu mẫu để tôi có thể sử dụng đối tượng đó để gửi dữ liệu trở lại máy chủ để được lưu.Cảnh báo Flex: Không thể liên kết với thuộc tính 'foo' trên lớp 'Đối tượng' (lớp không phải là trình duyệt IEventDispatcher)

Định nghĩa của đối tượng container của tôi:

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 được gán khi chạy đến một chỉ số cụ thể từ một ArrayCollection, tôi chỉ sử dụng các đối tượng emptyLink cho mục đích khởi tạo, chủ yếu.

<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> 

Tất nhiên, đây biên dịch và hiển thị tốt, nhưng có những cảnh báo thời gian chạy cho mỗi trường hợp:

cảnh báo: không thể để ràng buộc vào bất động sản 'trigger1' trên lớp 'Object' (lớp được không phải là một IEventDispatcher) cảnh báo: không thể liên kết với thuộc tính 'trigger2' trên lớp 'Object' (lớp không phải là IEventDispatcher) cảnh báo: không thể liên kết với thuộc tính 'trigger3' trên lớp 'Object' (lớp không phải là IEventDispatcher) Cảnh báo : không thể liên kết với thuộc tính 'trigger4' trên lớp 'Đối tượng' (lớp không phải là trình duyệt IEventDispatcher) cảnh báo: không thể để ràng buộc vào bất động sản 'trigger5' bật 'đối tượng' lớp (lớp không phải là một IEventDispatcher)

Và đối tượng currentLink không được cập nhật khi các lĩnh vực TextInput được thay đổi.

Câu trả lời rõ ràng là đối tượng của tôi cần phải là một thể hiện của một lớp thực hiện IEventDispatcher. Câu trả lời đó không nói với tôi là những chi tiết của việc thực hiện giao diện đó (cái gì là cần thiết? Cái gì không?), Và nếu có một cách đơn giản hơn để làm điều này - như lớp được xây dựng sẵn sàng chấp nhận thuộc tính tùy chỉnh của tôi và cho phép cho ràng buộc, mà không cần phải lo lắng về các đặc điểm của việc thực hiện giao diện.

Lớp học này có tồn tại không? Nếu không, tiêu chuẩn tối thiểu và/hoặc được chấp nhận là gì để hoàn thành nhiệm vụ này?

Trả lời

15

Bạn cần phải sử dụng ObjectProxy (như Chetan đề cập) - nhưng bạn cũng cần phải sử dụng valueCommit để có được những văn bản bạn nhập vào đầu vào trở lại vào đối tượng của bạn:

<?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> 
0

Tôi chưa sử dụng Flex trong thời gian dài và điều này có thể không phù hợp với yêu cầu của bạn, nhưng tại sao không sử dụng XML? Tôi tin rằng bạn có thể đặt giá trị văn bản TextInput thành các thuộc tính trong XML.

Tôi đang sử dụng pseudo-code, nhưng một cái gì đó như thế này có ý nghĩa với tôi:

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

Something như thế này, có lẽ?

8

Object không gửi sự kiện. Mặc dù bạn đã tạo biến Bindable, các thuộc tính của đối tượng được tham chiếu bởi biến số currentLink không thể bị ràng buộc.

Sử dụng ObjectProxy để thay thế.

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

Here's the livedocs reference cho giao diện. Nó là khá nhiều những gì sẽ được rõ ràng.

Để quote:

Nói chung, cách dễ nhất cho một lớp người dùng định nghĩa để đạt được khả năng cử sự kiện là mở rộng EventDispatcher.

Do đó,

tin const tĩnh emptyLink: EventDispatcher = {

+0

liên kết của bạn không chuyển đến trang bên trong các trang web mà bạn nghĩ. Mỗi trang tham chiếu của livedocs có "Liên kết hiện tại: ..." ở chân trang, với URL để liên kết trực tiếp trang bạn đang xem. Dùng nó. :) –

4

Điều đầu tiên bạn sẽ muốn biết là ràng buộc trong Flex 3 không phải là hai chiều. Biểu thức ràng buộc sẽ đảm bảo rằng nếu nguồn của biểu thức ràng buộc (currentLink.trigger1) thay đổi mục tiêu (TextInput) sẽ nhận được thông báo về thay đổi và cập nhật cho phù hợp. Nếu bạn muốn ràng buộc để đi theo một hướng khác, có ít nhất hai cách để làm điều này:

  1. Sử dụng mx: Ràng buộc thẻ để chỉ đạo TextInput.text trở lại đối tượng
  2. Sử dụng BindingUtils làm thay vào đó lập trình.

Trong Flex 4 họ đang giới thiệu một cú pháp mới cho hai chiều ràng buộc @ {} some.binding.expression nhưng nó không có sẵn trong Flex 3.

Trên phần thứ 2: lỗi mà bạn nhận được là vì bạn đang ràng buộc với một đối tượng nguyên mẫu "chung". Khi bạn áp dụng thẻ siêu dữ liệu [Bindable] cho thuộc tính hoặc lớp, trình biên dịch MXMLC tạo mã AS bao gồm việc sử dụng các tiện ích liên kết và trình theo dõi thay đổi thuộc tính để thực hiện việc ràng buộc xảy ra. Tuy nhiên bạn không thể làm cho Prototype làm điều này vì nó được tích hợp sẵn. Bạn có thể tạo một lớp ActionScript tùy chỉnh có thể ràng buộc (hoặc có các thuộc tính nhất định có thể ràng buộc). Trình biên dịch MXMLC sẽ tạo ra một lớp thực hiện IEventDispatcher và do đó hỗ trợ ràng buộc. Điều này có lợi thế là nhanh hơn các đối tượng nguyên mẫu và cũng cho phép bạn kiểm tra thời gian biên dịch, tức là bạn sẽ nhận được lỗi trình biên dịch nếu bạn tham chiếu thuộc tính không hợp lệ.

Cách khác là bọc nguyên mẫu của bạn trong ObjectProxy như một trong các thành viên SO khác đã đề xuất.

+0

Nếu tôi có thể chấp nhận 2 câu trả lời, câu trả lời này sẽ là # 2. Tôi đã chọn Gabriel vì đó là giải pháp đơn giản nhất để làm những gì tôi đang cố gắng làm. Cảm ơn tất cả các thông tin, mặc dù! –

1

Nói chung, lý do tại sao bạn nhận được "không thể liên kết với thuộc tính foo trên một lớp học, là bởi vì bạn hoặc là thiếu một getter hoặc setter cho foo.Bạn thể cũng làm cho foo scoped cho một biến công cộng, (mặc dù điều này phá vỡ đóng gói)

Vì vậy, bạn cần Cả hai để làm cho nó biến mất:

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

hoặc

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

Chỉ là mẹo về cách tìm mã vi phạm trong dự án lớn hơn - đặt điểm ngắt trên hai số

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

dòng trong lớp PropertyWatcher của SDK (Điều hướng> Loại mở> ...). Stacktrace sau đó sẽ giúp bạn tìm thấy thành phần ui giữ liên kết bị hỏng.