Trước khi tạo một loại trường mới, hãy cân nhắc xem một trong các phương thức khác để tuỳ chỉnh trường có phù hợp với nhu cầu của bạn hay không. Nếu ứng dụng của bạn cần lưu trữ một loại giá trị mới hoặc bạn muốn tạo một giao diện người dùng mới cho một loại giá trị hiện có, thì bạn có thể cần tạo một loại trường mới.
Để tạo trường mới, hãy làm như sau:
- Triển khai hàm khởi tạo.
- Đăng ký khoá JSON và triển khai
fromJson
. - Xử lý việc khởi chạy giao diện người dùng trên khối và trình nghe sự kiện.
- Xử lý việc loại bỏ trình nghe sự kiện (hệ thống sẽ xử lý việc loại bỏ giao diện người dùng cho bạn).
- Triển khai tính năng xử lý giá trị.
- Thêm nội dung văn bản thể hiện giá trị của trường để hỗ trợ tiếp cận.
- Thêm chức năng bổ sung, chẳng hạn như:
- Định cấu hình các khía cạnh khác của trường, chẳng hạn như:
Phần này giả định rằng bạn đã đọc và nắm rõ nội dung trong bài viết Cấu trúc của một trường.
Để biết ví dụ về trường tuỳ chỉnh, hãy xem Bản minh hoạ về trường tuỳ chỉnh.
Triển khai hàm khởi tạo
Hàm khởi tạo của trường chịu trách nhiệm thiết lập giá trị ban đầu của trường và tuỳ ý thiết lập trình xác thực cục bộ. Hàm khởi tạo của trường tuỳ chỉnh được gọi trong quá trình khởi tạo khối nguồn, bất kể khối nguồn được xác định trong JSON hay JavaScript. Do đó, trường tuỳ chỉnh không có quyền truy cập vào khối nguồn trong quá trình tạo.
Mã mẫu sau đây tạo một trường tuỳ chỉnh có tên là GenericField
:
class GenericField extends Blockly.Field {
constructor(value, validator) {
super(value, validator);
this.SERIALIZABLE = true;
}
}
Chữ ký phương thức
Hàm khởi tạo trường thường nhận một giá trị và một trình xác thực cục bộ. Giá trị này là không bắt buộc và nếu bạn không truyền giá trị (hoặc truyền giá trị không hợp lệ với lớp) thì giá trị mặc định của lớp cha sẽ được sử dụng. Đối với lớp Field
mặc định, giá trị đó là null
. Nếu bạn không muốn giá trị mặc định đó, hãy nhớ truyền một giá trị phù hợp. Tham số trình xác thực chỉ xuất hiện đối với các trường có thể chỉnh sửa và thường được đánh dấu là không bắt buộc. Tìm hiểu thêm về trình xác thực trong tài liệu về trình xác thực.
Cấu trúc
Logic bên trong hàm khởi tạo phải tuân theo quy trình sau:
- Gọi hàm khởi tạo cấp trên được kế thừa (tất cả các trường tuỳ chỉnh phải kế thừa từ
Blockly.Field
hoặc một trong các lớp con của hàm này) để khởi tạo đúng giá trị và đặt trình xác thực cục bộ cho trường của bạn. - Nếu trường của bạn có thể chuyển đổi tuần tự, hãy đặt thuộc tính tương ứng trong hàm khởi tạo. Các trường có thể chỉnh sửa phải có thể chuyển đổi tuần tự và các trường có thể chỉnh sửa theo mặc định, vì vậy, bạn nên đặt thuộc tính này thành true trừ khi bạn biết rằng thuộc tính này không thể chuyển đổi tuần tự.
- Không bắt buộc: Áp dụng tuỳ chỉnh bổ sung (ví dụ: Trường nhãn cho phép truyền một lớp css, sau đó áp dụng lớp này cho văn bản).
JSON và đăng ký
Trong định nghĩa khối JSON, các trường được mô tả bằng một chuỗi (ví dụ: field_number
, field_textinput
). Blockly duy trì một bản đồ từ các chuỗi này đến các đối tượng trường và gọi fromJson
trên đối tượng thích hợp trong quá trình tạo.
Gọi Blockly.fieldRegistry.register
để thêm loại trường vào bản đồ này, truyền vào lớp trường làm đối số thứ hai:
Blockly.fieldRegistry.register('field_generic', GenericField);
Bạn cũng cần xác định hàm fromJson
. Trước tiên, bạn nên triển khai việc huỷ tham chiếu mọi tham chiếu đến mã thông báo bản địa hoá bằng cách sử dụng replaceMessageReferences, sau đó truyền các giá trị đó đến hàm khởi tạo.
GenericField.fromJson = function(options) {
const value = Blockly.utils.parsing.replaceMessageReferences(
options['value']);
return new CustomFields.GenericField(value);
};
Đang khởi tạo
Khi được tạo, trường của bạn về cơ bản chỉ chứa một giá trị. Quá trình khởi tạo là nơi tạo DOM, tạo mô hình (nếu trường sở hữu mô hình) và liên kết các sự kiện.
Màn hình trên khối
Trong quá trình khởi tạo, bạn chịu trách nhiệm tạo mọi thứ cần thiết cho màn hình trên khối của trường.
Mặc định, nền và văn bản
Hàm initView
mặc định tạo một phần tử rect
có màu sáng và một phần tử text
. Nếu bạn muốn trường của mình có cả hai thuộc tính này cùng với một số tính năng bổ sung, hãy gọi hàm initView
của lớp cao cấp trước khi thêm các phần tử DOM còn lại. Nếu muốn trường của mình có một trong các phần tử này (chứ không phải cả hai), bạn có thể sử dụng hàm createBorderRect_
hoặc createTextElement_
.
Tuỳ chỉnh quá trình tạo DOM
Nếu trường của bạn là trường văn bản chung (ví dụ: Text Input (Văn bản đầu vào)), thì việc tạo DOM sẽ được xử lý cho bạn. Nếu không, bạn sẽ cần ghi đè hàm initView
để tạo các phần tử DOM mà bạn sẽ cần trong quá trình kết xuất trường trong tương lai.
Ví dụ: một trường thả xuống có thể chứa cả hình ảnh và văn bản. Trong initView
, lớp này tạo một phần tử hình ảnh và một phần tử văn bản. Sau đó, trong render_
, lớp này sẽ hiển thị phần tử đang hoạt động và ẩn phần tử còn lại, dựa trên loại của tuỳ chọn đã chọn.
Bạn có thể tạo phần tử DOM bằng phương thức Blockly.utils.dom.createSvgElement
hoặc bằng các phương thức tạo DOM truyền thống.
Các yêu cầu đối với chế độ hiển thị trên khối của một trường là:
- Tất cả phần tử DOM phải là phần tử con của
fieldGroup_
của trường. Nhóm trường được tạo tự động. - Tất cả phần tử DOM phải nằm trong kích thước được báo cáo của trường.
Hãy xem phần Hiển thị để biết thêm thông tin về cách tuỳ chỉnh và cập nhật màn hình trên khối.
Thêm ký hiệu văn bản
Nếu muốn thêm biểu tượng vào văn bản của một trường (chẳng hạn như biểu tượng độ của trường Angle (Góc)), bạn có thể thêm trực tiếp phần tử biểu tượng (thường nằm trong <tspan>
) vào textElement_
của trường.
Sự kiện nhập
Theo mặc định, các trường sẽ đăng ký sự kiện chú giải công cụ và sự kiện nhấp chuột (để dùng cho việc hiển thị trình chỉnh sửa).
Nếu muốn nghe các loại sự kiện khác (ví dụ: nếu muốn xử lý việc kéo trên một trường), bạn nên ghi đè hàm bindEvents_
của trường.
bindEvents_() {
// Call the superclass function to preserve the default behavior as well.
super.bindEvents_();
// Then register your own additional event listeners.
this.mouseDownWrapper_ =
Blockly.browserEvents.conditionalBind(this.getClickTarget_(), 'mousedown', this,
function(event) {
this.originalMouseX_ = event.clientX;
this.isMouseDown_ = true;
this.originalValue_ = this.getValue();
event.stopPropagation();
}
);
this.mouseMoveWrapper_ =
Blockly.browserEvents.conditionalBind(document, 'mousemove', this,
function(event) {
if (!this.isMouseDown_) {
return;
}
var delta = event.clientX - this.originalMouseX_;
this.setValue(this.originalValue_ + delta);
}
);
this.mouseUpWrapper_ =
Blockly.browserEvents.conditionalBind(document, 'mouseup', this,
function(_event) {
this.isMouseDown_ = false;
}
);
}
Để liên kết với một sự kiện, bạn thường nên sử dụng hàm Blockly.utils.browserEvents.conditionalBind
. Phương thức liên kết sự kiện này lọc ra các thao tác chạm phụ trong quá trình kéo. Nếu muốn trình xử lý của bạn chạy ngay cả khi đang kéo, bạn có thể sử dụng hàm Blockly.browserEvents.bind
.
Xử lý
Nếu bạn đã đăng ký bất kỳ trình nghe sự kiện tuỳ chỉnh nào bên trong hàm bindEvents_
của trường, thì bạn cần huỷ đăng ký các trình nghe đó bên trong hàm dispose
.
Nếu bạn đã khởi chạy thành công thành phần hiển thị của trường (bằng cách thêm tất cả phần tử DOM vào fieldGroup_
), thì DOM của trường sẽ được tự động xử lý.
Xử lý giá trị
→ Để biết thông tin về giá trị của trường so với văn bản của trường, hãy xem phần Cấu trúc của trường.
Thứ tự xác thực
Triển khai trình xác thực lớp
Các trường chỉ được chấp nhận một số giá trị nhất định. Ví dụ: trường số chỉ chấp nhận số, trường màu chỉ chấp nhận màu, v.v. Điều này được đảm bảo thông qua lớp và trình xác thực cục bộ. Trình xác thực lớp tuân theo các quy tắc giống như trình xác thực cục bộ, ngoại trừ việc trình xác thực này cũng chạy trong hàm khởi tạo và do đó, trình xác thực này không được tham chiếu đến khối nguồn.
Để triển khai trình xác thực lớp của trường, hãy ghi đè hàm doClassValidation_
.
doClassValidation_(newValue) {
if (typeof newValue != 'string') {
return null;
}
return newValue;
};
Xử lý các giá trị hợp lệ
Nếu giá trị được truyền đến một trường có setValue
hợp lệ, bạn sẽ nhận được lệnh gọi lại doValueUpdate_
. Theo mặc định, hàm doValueUpdate_
:
- Đặt thuộc tính
value_
thànhnewValue
. - Đặt thuộc tính
isDirty_
thànhtrue
.
Nếu chỉ cần lưu trữ giá trị và không muốn xử lý tuỳ chỉnh, bạn không cần ghi đè doValueUpdate_
.
Nếu không, nếu bạn muốn thực hiện các thao tác như:
- Bộ nhớ tuỳ chỉnh của
newValue
. - Thay đổi các thuộc tính khác dựa trên
newValue
. - Lưu liệu giá trị hiện tại có hợp lệ hay không.
Bạn sẽ cần ghi đè doValueUpdate_
:
doValueUpdate_(newValue) {
super.doValueUpdate_(newValue);
this.displayValue_ = newValue;
this.isValueValid_ = true;
}
Xử lý các giá trị không hợp lệ
Nếu giá trị được truyền đến trường có setValue
không hợp lệ, bạn sẽ nhận được lệnh gọi lại doValueInvalid_
. Theo mặc định, hàm doValueInvalid_
không làm gì cả. Điều này có nghĩa là theo mặc định, các giá trị không hợp lệ sẽ không xuất hiện. Điều này cũng có nghĩa là trường sẽ không được kết xuất lại vì thuộc tính isDirty_
sẽ không được đặt.
Nếu muốn hiển thị các giá trị không hợp lệ, bạn nên ghi đè doValueInvalid_
.
Trong hầu hết các trường hợp, bạn nên đặt thuộc tính displayValue_
thành giá trị không hợp lệ, đặt isDirty_
thành true
và ghi đè chế độ hiển thị trên khối để cập nhật dựa trên displayValue_
thay vì value_
.
doValueInvalid_(newValue) {
this.displayValue_ = newValue;
this.isDirty_ = true;
this.isValueValid_ = false;
}
Giá trị nhiều phần
Khi trường của bạn chứa một giá trị nhiều phần (ví dụ: danh sách, vectơ, đối tượng), bạn có thể muốn các phần được xử lý như các giá trị riêng lẻ.
doClassValidation_(newValue) {
if (FieldTurtle.PATTERNS.indexOf(newValue.pattern) == -1) {
newValue.pattern = null;
}
if (FieldTurtle.HATS.indexOf(newValue.hat) == -1) {
newValue.hat = null;
}
if (FieldTurtle.NAMES.indexOf(newValue.turtleName) == -1) {
newValue.turtleName = null;
}
if (!newValue.pattern || !newValue.hat || !newValue.turtleName) {
this.cachedValidatedValue_ = newValue;
return null;
}
return newValue;
}
Trong ví dụ trên, mỗi thuộc tính của newValue
được xác thực riêng lẻ. Sau đó, ở cuối hàm doClassValidation_
, nếu bất kỳ thuộc tính riêng lẻ nào không hợp lệ, thì giá trị sẽ được lưu vào bộ nhớ đệm của thuộc tính cacheValidatedValue_
trước khi trả về null
(không hợp lệ). Việc lưu đối tượng vào bộ nhớ đệm với các thuộc tính được xác thực riêng lẻ cho phép hàm doValueInvalid_
xử lý riêng từng thuộc tính, chỉ bằng cách kiểm tra !this.cacheValidatedValue_.property
, thay vì xác thực lại từng thuộc tính riêng lẻ.
Bạn cũng có thể sử dụng mẫu này để xác thực các giá trị nhiều phần trong trình xác thực cục bộ, nhưng hiện tại không có cách nào để thực thi mẫu này.
isDirty_
isDirty_
là một cờ được dùng trong hàm setValue
cũng như các phần khác của trường để cho biết liệu trường có cần được kết xuất lại hay không. Nếu giá trị hiển thị của trường đã thay đổi, thì bạn thường nên đặt isDirty_
thành true
.
Văn bản
→ Để biết thông tin về vị trí sử dụng văn bản của trường và sự khác biệt giữa văn bản và giá trị của trường, hãy xem phần Kết cấu của trường.
Nếu văn bản của trường khác với giá trị của trường, bạn nên ghi đè hàm getText
để cung cấp văn bản chính xác.
getText() {
let text = this.value_.turtleName + ' wearing a ' + this.value_.hat;
if (this.value_.hat == 'Stovepipe' || this.value_.hat == 'Propeller') {
text += ' hat';
}
return text;
}
Tạo trình chỉnh sửa
Nếu bạn xác định hàm showEditor_
, Blockly sẽ tự động nghe các lượt nhấp và gọi showEditor_
vào thời điểm thích hợp. Bạn có thể hiển thị bất kỳ HTML nào trong trình chỉnh sửa bằng cách gói HTML đó vào một trong hai div đặc biệt, được gọi là DropDownDiv và WidgetDiv, nổi phía trên phần còn lại của giao diện người dùng Blockly.
DropDownDiv so với WidgetDiv
DropDownDiv
được dùng để cung cấp trình chỉnh sửa nằm bên trong một hộp được kết nối với một trường. Nút này tự động định vị gần trường trong khi vẫn nằm trong giới hạn hiển thị. Công cụ chọn góc và công cụ chọn màu là những ví dụ điển hình về DropDownDiv
.
WidgetDiv
được dùng để cung cấp các trình chỉnh sửa không nằm trong hộp. Các trường số sử dụng WidgetDiv để bao phủ trường bằng hộp nhập văn bản HTML. Mặc dù DropDownDiv xử lý việc định vị cho bạn, nhưng WidgetDiv thì không. Bạn sẽ cần đặt vị trí các phần tử theo cách thủ công. Hệ toạ độ ở dạng toạ độ pixel so với góc trên cùng bên trái của cửa sổ. Trình chỉnh sửa nhập văn bản là một ví dụ điển hình về WidgetDiv
.
Mã mẫu DropDownDiv
showEditor_() {
// Create the widget HTML
this.editor_ = this.dropdownCreate_();
Blockly.DropDownDiv.getContentDiv().appendChild(this.editor_);
// Set the dropdown's background colour.
// This can be used to make it match the colour of the field.
Blockly.DropDownDiv.setColour('white', 'silver');
// Show it next to the field. Always pass a dispose function.
Blockly.DropDownDiv.showPositionedByField(
this, this.disposeWidget_.bind(this));
}
Mã mẫu WidgetDiv
showEditor_() {
// Show the div. This automatically closes the dropdown if it is open.
// Always pass a dispose function.
Blockly.WidgetDiv.show(
this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this));
// Create the widget HTML.
var widget = this.createWidget_();
Blockly.WidgetDiv.getDiv().appendChild(widget);
}
Dọn dẹp
Cả DropDownDiv và WidgetDiv đều xử lý việc huỷ các phần tử HTML của tiện ích, nhưng bạn cần phải tự loại bỏ mọi trình nghe sự kiện mà bạn đã áp dụng cho các phần tử đó.
widgetDispose_() {
for (let i = this.editorListeners_.length, listener;
listener = this.editorListeners_[i]; i--) {
Blockly.browserEvents.unbind(listener);
this.editorListeners_.pop();
}
}
Hàm dispose
được gọi trong ngữ cảnh null
trên DropDownDiv
. Trên WidgetDiv
, phương thức này được gọi trong ngữ cảnh của WidgetDiv
. Trong cả hai trường hợp, tốt nhất bạn nên sử dụng hàm bind khi truyền hàm huỷ, như trong ví dụ DropDownDiv
và WidgetDiv
ở trên.
→ Để biết thông tin về việc loại bỏ không dành riêng cho việc loại bỏ trình chỉnh sửa, hãy xem phần Loại bỏ.
Cập nhật màn hình trên khối
Hàm render_
được dùng để cập nhật màn hình hiển thị trên khối của trường cho khớp với giá trị nội bộ của trường.
Sau đây là một số ví dụ thường gặp:
- Thay đổi văn bản (trình đơn thả xuống)
- Thay đổi màu (color)
Mặc định
Hàm render_
mặc định đặt văn bản hiển thị thành kết quả của hàm getDisplayText_
. Hàm getDisplayText_
trả về thuộc tính value_
của trường được truyền vào một chuỗi, sau khi thuộc tính này bị cắt bớt để tuân theo độ dài văn bản tối đa.
Nếu đang sử dụng màn hình trên khối mặc định và hành vi văn bản mặc định hoạt động cho trường của bạn, thì bạn không cần ghi đè render_
.
Nếu hành vi văn bản mặc định hoạt động cho trường của bạn, nhưng màn hình trên khối của trường có các phần tử tĩnh bổ sung, bạn có thể gọi hàm render_
mặc định, nhưng bạn vẫn cần ghi đè hàm này để cập nhật kích thước của trường.
Nếu hành vi văn bản mặc định không hoạt động cho trường của bạn hoặc màn hình trên khối của trường có các phần tử động bổ sung, bạn sẽ cần tuỳ chỉnh hàm render_
.
Tuỳ chỉnh chế độ hiển thị
Nếu hành vi hiển thị mặc định không hoạt động cho trường của bạn, bạn sẽ cần xác định hành vi hiển thị tuỳ chỉnh. Điều này có thể liên quan đến mọi thứ, từ việc đặt văn bản hiển thị tuỳ chỉnh, thay đổi các thành phần hình ảnh cho đến việc cập nhật màu nền.
Tất cả thay đổi đối với thuộc tính DOM đều hợp pháp, bạn chỉ cần nhớ hai điều sau:
- Bạn nên xử lý việc tạo DOM trong quá trình khởi chạy vì cách này hiệu quả hơn.
- Bạn phải luôn cập nhật thuộc tính
size_
để khớp với kích thước của màn hình trên khối.
render_() {
switch(this.value_.hat) {
case 'Stovepipe':
this.stovepipe_.style.display = '';
break;
case 'Crown':
this.crown_.style.display = '';
break;
case 'Mask':
this.mask_.style.display = '';
break;
case 'Propeller':
this.propeller_.style.display = '';
break;
case 'Fedora':
this.fedora_.style.display = '';
break;
}
switch(this.value_.pattern) {
case 'Dots':
this.shellPattern_.setAttribute('fill', 'url(#polkadots)');
break;
case 'Stripes':
this.shellPattern_.setAttribute('fill', 'url(#stripes)');
break;
case 'Hexagons':
this.shellPattern_.setAttribute('fill', 'url(#hexagons)');
break;
}
this.textContent_.nodeValue = this.value_.turtleName;
this.updateSize_();
}
Cập nhật kích thước
Việc cập nhật thuộc tính size_
của một trường là rất quan trọng vì thuộc tính này cho mã kết xuất khối biết cách định vị trường. Cách tốt nhất để tìm ra chính xác size_
đó là thử nghiệm.
updateSize_() {
const bbox = this.movableGroup_.getBBox();
let width = bbox.width;
let height = bbox.height;
if (this.borderRect_) {
width += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
height += this.constants_.FIELD_BORDER_RECT_X_PADDING * 2;
this.borderRect_.setAttribute('width', width);
this.borderRect_.setAttribute('height', height);
}
// Note how both the width and the height can be dynamic.
this.size_.width = width;
this.size_.height = height;
}
Phối màu khối
Nếu muốn các phần tử của trường khớp với màu của khối mà các phần tử đó được đính kèm, bạn nên ghi đè phương thức applyColour
. Bạn sẽ muốn truy cập vào màu thông qua thuộc tính kiểu của khối.
applyColour() {
const sourceBlock = this.sourceBlock_;
if (sourceBlock.isShadow()) {
this.arrow_.style.fill = sourceBlock.style.colourSecondary;
} else {
this.arrow_.style.fill = sourceBlock.style.colourPrimary;
}
}
Cập nhật khả năng chỉnh sửa
Bạn có thể sử dụng hàm updateEditable
để thay đổi cách trường xuất hiện, tuỳ thuộc vào việc trường đó có thể chỉnh sửa hay không. Hàm mặc định giúp nền có/không có phản hồi khi di chuột (viền) nếu nền có thể/không thể chỉnh sửa.
Màn hình trên khối không được thay đổi kích thước tuỳ thuộc vào khả năng chỉnh sửa, nhưng tất cả các thay đổi khác đều được phép.
updateEditable() {
if (!this.fieldGroup_) {
// Not initialized yet.
return;
}
super.updateEditable();
const group = this.getClickTarget_();
if (!this.isCurrentlyEditable()) {
group.style.cursor = 'not-allowed';
} else {
group.style.cursor = this.CURSOR;
}
}
Chuyển đổi tuần tự
Sê-ri hoá là về việc lưu trạng thái của trường để có thể tải lại trường đó vào không gian làm việc sau này.
Trạng thái của không gian làm việc luôn bao gồm giá trị của trường, nhưng cũng có thể bao gồm trạng thái khác, chẳng hạn như trạng thái của giao diện người dùng của trường. Ví dụ: nếu trường của bạn là một bản đồ có thể thu phóng cho phép người dùng chọn quốc gia, thì bạn cũng có thể chuyển đổi tuần tự cấp độ thu phóng.
Nếu trường của bạn có thể chuyển đổi tuần tự, bạn phải đặt thuộc tính SERIALIZABLE
thành true
.
Blockly cung cấp hai bộ trình chuyển đổi tuần tự cho các trường. Một cặp trình bổ trợ hoạt động với hệ thống chuyển đổi tuần tự JSON mới và cặp còn lại hoạt động với hệ thống chuyển đổi tuần tự XML cũ.
saveState
và loadState
saveState
và loadState
là các trình nối chuyển đổi tuần tự hoạt động với hệ thống chuyển đổi tuần tự JSON mới.
Trong một số trường hợp, bạn không cần cung cấp các thông tin này vì các phương thức triển khai mặc định sẽ hoạt động. Nếu (1) trường của bạn là lớp con trực tiếp của lớp Blockly.Field
cơ sở, (2) giá trị của bạn là loại có thể chuyển đổi tuần tự JSON và (3) bạn chỉ cần chuyển đổi tuần tự giá trị, thì phương thức triển khai mặc định sẽ hoạt động tốt!
Nếu không, hàm saveState
sẽ trả về một đối tượng/giá trị JSON có thể chuyển đổi tuần tự đại diện cho trạng thái của trường. Và hàm loadState
của bạn phải chấp nhận cùng một đối tượng/giá trị JSON có thể chuyển đổi tuần tự và áp dụng đối tượng/giá trị đó cho trường.
saveState() {
return {
'country': this.getValue(), // Value state
'zoom': this.getZoomLevel(), // UI state
};
}
loadState(state) {
this.setValue(state['country']);
this.setZoomLevel(state['zoom']);
}
Trình tự hoá đầy đủ và dữ liệu sao lưu
saveState
cũng nhận được một tham số không bắt buộc là doFullSerialization
. Trường này được sử dụng bởi các trường thường tham chiếu trạng thái được chuyển đổi tuần tự bằng một trình chuyển đổi tuần tự khác (chẳng hạn như mô hình dữ liệu sao lưu). Tham số này cho biết rằng trạng thái được tham chiếu sẽ không có sẵn khi khối được chuyển đổi tuần tự, vì vậy, trường này sẽ tự thực hiện tất cả các quá trình chuyển đổi tuần tự. Ví dụ: điều này đúng khi một khối riêng lẻ được chuyển đổi tuần tự hoặc khi một khối được sao chép và dán.
Có hai trường hợp sử dụng phổ biến cho việc này:
- Khi một khối riêng lẻ được tải vào không gian làm việc không có mô hình dữ liệu sao lưu, trường này có đủ thông tin ở trạng thái riêng để tạo một mô hình dữ liệu mới.
- Khi một khối được sao chép và dán, trường này luôn tạo một mô hình dữ liệu sao lưu mới thay vì tham chiếu đến mô hình hiện có.
Một trường sử dụng tính năng này là trường biến tích hợp. Thông thường, phương thức này sẽ chuyển đổi tuần tự mã nhận dạng của biến mà nó đang tham chiếu, nhưng nếu doFullSerialization
là true, thì phương thức này sẽ chuyển đổi tuần tự tất cả trạng thái của biến.
saveState(doFullSerialization) {
const state = {'id': this.variable_.getId()};
if (doFullSerialization) {
state['name'] = this.variable_.name;
state['type'] = this.variable_.type;
}
return state;
}
loadState(state) {
const variable = Blockly.Variables.getOrCreateVariablePackage(
this.getSourceBlock().workspace,
state['id'],
state['name'], // May not exist.
state['type']); // May not exist.
this.setValue(variable.getId());
}
Trường biến thực hiện việc này để đảm bảo rằng nếu được tải vào một không gian làm việc mà biến của trường không tồn tại, thì trường có thể tạo một biến mới để tham chiếu.
toXml
và fromXml
toXml
và fromXml
là các trình nối tuần tự hoạt động với hệ thống tuần tự hoá XML cũ. Chỉ sử dụng các trình bổ trợ này nếu bạn phải làm vậy (ví dụ: bạn đang làm việc trên một cơ sở mã cũ chưa di chuyển), nếu không, hãy sử dụng saveState
và loadState
.
Hàm toXml
của bạn phải trả về một nút XML đại diện cho trạng thái của trường. Và hàm fromXml
của bạn phải chấp nhận cùng một nút XML và áp dụng nút đó cho trường.
toXml(fieldElement) {
fieldElement.textContent = this.getValue();
fieldElement.setAttribute('zoom', this.getZoomLevel());
return fieldElement;
}
fromXml(fieldElement) {
this.setValue(fieldElement.textContent);
this.setZoomLevel(fieldElement.getAttribute('zoom'));
}
Các thuộc tính có thể chỉnh sửa và chuyển đổi tuần tự
Thuộc tính EDITABLE
xác định xem trường có cần giao diện người dùng để cho biết có thể tương tác với trường đó hay không. Giá trị mặc định là true
.
Thuộc tính SERIALIZABLE
xác định xem trường có được chuyển đổi tuần tự hay không. Giá trị mặc định là false
. Nếu thuộc tính này là true
, bạn có thể cần cung cấp các hàm chuyển đổi tuần tự và huỷ chuyển đổi tuần tự (xem phần Chuyển đổi tuần tự).
Tuỳ chỉnh con trỏ
Thuộc tính CURSOR
xác định con trỏ mà người dùng nhìn thấy khi họ di chuột qua trường của bạn. Đó phải là một chuỗi con trỏ CSS hợp lệ. Giá trị này mặc định là con trỏ do .blocklyDraggable
xác định, tức là con trỏ thu thập.