Trung Tâm Đào Tạo Mạng Máy Tính Nhất Nghệ

Trung Tâm Đào Tạo Mạng Máy Tính Nhất Nghệ (http://www.nhatnghe.com/forum/index.php)
-   FLEX (http://www.nhatnghe.com/forum/forumdisplay.php?f=146)
-   -   Xây dựng component trong Flex (http://www.nhatnghe.com/forum/showthread.php?t=203666)

quangngoc186 17-08-2011 21:53

Xây dựng component trong Flex
 
Chào mọi người!

Mình đang tìm hiểu cách xây dựng một component tùy biến kế thừa từ lớp UIComponent, nhưng không biết cách thức làm việc của nó như thế nào nữa. Ai đã làm phần này rồi hướng dẫn giúp mình với.

Cụ thể mình đang muốn viết một component như link này http://blog.flexdevelopers.com/2010/...-combobox.html. Lấy giá trị từ DataGrid đổ vào ComboBox, và giờ muốn lấy giá trị từ ComboBox để lưu vào dữ liệu lại khi có thay đổi giá trị.

Cảm ơn rất nhiều,

ncom 06-09-2011 19:59

Mục đích của việc subclass một component nào đó là để dùng lại component đó mãi về sau trong cùng project hoặc project khác. Với yêu cầu đổ dữ liệu qua lại phía trên, nếu không liên quan đến việc dùng lại thì không cần subclass ComboBox, chỉ cần duy nhất một hàm changeHandler xử lý sự kiện change chung cho cả 2 component là đủ, trong đó bắt lấy cái currentTarget để xem cái nào vừa change rồi thay đổi giá trị tương ứng cho cái kia.

Ví dụ trong link trên subclass ComboBox vì họ muốn dùng lại ComboBox này về sau. Khi đó, ComboBox đóng vai trò chính trong việc xử lý, DataGrid chỉ đóng vai trò phụ và tác dụng duy nhất của DataGrid nằm ở cái binding khi tạo instance cho ComboBox:

selectedValue="{dgAddresses.selectedItem.State}"

Dòng binding này chính là lối vào. Quy trình được giải thích như sau:

1. Mỗi khi chọn một dòng khác trên DataGrid, giá trị selectedItem của DataGrid thay đổi

2. selectedItem của DataGrid thay đổi khiến selectedItem.State thay đổi

3. Kéo theo thuộc tính selectedValue (thuộc tính tự đặt, không phải thuộc tính gốc) của ComboBox thay đổi (vì hai cái binding với nhau, source thay đổi khiến destination thay đổi theo).

4. Có được selectedValue mới, chuyện gì sẽ xảy ra? Sẽ không có chuyện gì xảy ra cho đến khi có sự kiện gì đó khiến ComboBox hiểu rằng vừa có sự thay đổi và nó phải refresh lại bằng cách thực thi hàm commitProperties(). Để chủ động thông báo cho nó đã có sự thay đổi xảy ra và hãy refresh lại ngay lập tức, developer phải tự gọi hàm invalidateProperties().

Khi đó, ComboBox sẽ không đợi nữa mà sẽ lập tức thực thi hàm commitProperties(), trong hàm đó tác giả đã override để thêm vào một vòng lặp duyệt qua các dòng trên dataProvider của ComboBox để tìm ra dòng có ô dữ liệu trùng với giá trị chứa trong selectedValue (ô này nằm trên cột tên là "data", chuỗi "data" này mặc định chứa trong biến tự đặt dataProperty, có thể thay bằng tên cột khác khi khởi tạo ComboBox; dataProperty cũng là thuộc tính tự đặt).

Đơn giản như vậy thôi. Còn cái collectionChangeHandler() chỉ là trường hợp phụ tác giả thêm vào để hoàn thiện hơn. Nó kiểm tra lại trong trường hợp dataProvider của ComboBox được thêm, sửa, xóa một dòng nào đó thì ComboBox cũng sẽ phải làm tương tự như khi selectedValue thay đổi.

Tóm lại, Flex luôn theo phong cách này: Hoặc là đợi một sự kiện xảy ra, sự kiện sẽ bật trigger gọi một hàm nào đó; còn nếu muốn gọi ngay hàm xử lý thì sẽ phải tự gọi một hàm thông báo để thay thế event bật trigger, trong trường hợp này là hàm invalidateProperties(). Khi subclass một component, hai hàm invalidateProperties() và commitProperties() thường xuyên được dùng cùng nhau.

ncom 06-09-2011 20:26

Phía trên là giải thích sơ lược về việc subclass, tạo component mới trong Flex.

Còn để thỏa mãn yêu cầu thứ hai, khi chọn dữ liệu khác trên ComboBox sẽ tác động ngược lại DataGrid, thử cách này:

1. Giả sử đặt lại tên cho ComboBox trong ví dụ trên là cb1, DataGrid là dg1

2. Đã có binding một chiều khi tạo ComboBox, bây giờ thêm thẻ binding ngược này vào, đặt ngay trên dòng </Application> cho dễ nhìn:

<mx:Binding source="cb1.selectedValue" destination="dg1.selectedItem.State" />

3. Viết hàm changeHandler cho cb1 làm 2 việc:

- Gán giá trị mới chọn vào cho biến selectedValue của ComboBox, nó sẽ gọi cái binding phía trên để thay đổi giá trị dg1.selectedItem.State hiện tại. Lưu ý: Sửa cái component, thêm cái [Bindable] vào ngay trên setter selectedValue để binding có tác dụng.

cb1.selectedValue = cb1.selectedItem.data;

- Để refresh lại dg1 và hiển thị sự thay đổi, gọi dg1.dataProvider.itemUpdated(dg1.selectedItem)

quangngoc186 07-09-2011 14:15

Cảm ơn Nhà truyền giáo Flex rất nhiều. Để làm lại thử được thì lên chia sẽ lại với mọi người. :07:


Múi giờ GMT +7. Hiện tại là 17:21

Powered by: vBulletin Version 3.8.7
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
Ad Management by RedTyger