Nâng cấp trường tuỳ chỉnh

Trong tháng 7 năm 2019 (bản phát hành 2.20190722), chúng tôi đã thêm một API trường được mã hoá kỹ hơn. Thư viện này được thiết kế để có khả năng tương thích ngược nhất có thể. Điều này có nghĩa là nếu bạn đã tạo một trường tuỳ chỉnh trước tháng 7 năm 2019, thì trường đó rất có thể sẽ tiếp tục hoạt động. Trước khi quyết định xem có cần nâng cấp trường tuỳ chỉnh hay không, bạn nên đọc qua phần Khu vực nguy hiểm và kiểm thử kỹ lưỡng trường của bạn.

Vì các trường trước tháng 7 năm 2019 thiếu tiêu chuẩn hoá nên rất khó để ghi nhận tất cả những thay đổi mà nhà phát triển có thể cần thực hiện. Tài liệu này cố gắng đề cập đến tất cả thay đổi có thể xảy ra, nhưng nếu tài liệu này không đề cập đến nội dung bạn quan tâm, vui lòng đọc phần nhận hỗ trợ nâng cấp.

Khu vực nguy hiểm

Các khu vực nguy hiểm được biết là nơi API đã thay đổi và trường của bạn có thể bị hỏng.

Blockly.Field.register

Các trường không còn được đăng ký thông qua Blockly.Field.register(); nữa. Hiện tại sẽ có một vùng chứa tên fieldRegistry xử lý việc đăng ký.

Blockly.Field.register('my_field_name', myFieldClass);

Trở thành:

Blockly.fieldRegistry.register('my_field_name', myFieldClass);

setText

Hàm setText không còn được lõi Blockly gọi, vì vậy, nếu hàm setText chứa logic, thì hàm đó cần được chuyển sang bộ hàm xử lý giá trị, hàm getTexthàm kết xuất (tuỳ thuộc vào chính xác chức năng của hàm setText).

CustomFields.UpgradeField.prototype.setText = function(newText) {
  // Do validation.
  if (typeof newText != 'string' || newText === this.text_) {
    return;
  }

  // Fire event.
  if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
    Blockly.events.fire(new Blockly.Events.BlockChange(
        this.sourceBlock_, 'field', this.name, this.text_, newText
    ));
  }

  // Update text value.
  this.text_ = 'prefix' + newText;

  // Rerender.
  this.size_.width = 0;
};

Trở thành:

CustomFields.UpgradeField.prototype.doClassValidation_ = function(newValue) {
  if (typeof newValue != 'string') {
    return null;
  }
  return newValue;
};

CustomFields.UpgradeField.prototype.getText = function() {
  return  'prefix' + this.value_;
}

Chặn tự động xử lý:

  • Kiểm tra xem giá trị mới có khác với giá trị cũ hay không.
  • Đang cập nhật giá trị.
  • Kích hoạt sự kiện thay đổi.
  • Đang kết xuất lại trường.

Bạn sẽ cần xử lý:

Đề xuất nâng cấp là những nơi API trường đã bị thay đổi, nhưng nếu bạn chọn không thực hiện thay đổi, trường của bạn rất có thể vẫn hoạt động.

CÓ THỂ KẾT NỐI

Để biết thêm thông tin về các thuộc tính EDITABLESERIALIZABLE, hãy xem bài viết Các thuộc tính có thể chỉnh sửa và chuyển đổi tuần tự.

CustomFields.UpgradeField.prototype.SERIALIZABLE = true;

Cảnh báo bên dưới không thể bỏ qua, nhưng bạn có thể giải quyết bằng cách xác định thuộc tính SERIALIZABLE:

Detected an editable field that was not serializable. Please define
SERIALIZABLE property as true on all editable custom fields. Proceeding
with serialization.

Cảnh báo ở trên có nghĩa là Blockly cho rằng bạn muốn trường được chuyển đổi tuần tự (vì thuộc tính EDITABLE là true), nhưng bạn không thể chắc chắn cho đến khi xác định thuộc tính SERIALIZABLE. Nếu bạn chọn giữ nguyên phương thức này, mọi thứ sẽ hoạt động đúng cách và trường của bạn sẽ được chuyển đổi tuần tự, nhưng bạn sẽ nhận được cảnh báo trên bảng điều khiển.

size_.width

this.size_.width = 0;

Trở thành:

this.isDirty_ = true;

Cảnh báo bên dưới không thể bỏ qua, nhưng bạn có thể giải quyết bằng cách đặt thuộc tính isDirty_ thay vì thuộc tính size_.width:

Deprecated use of setting size_.width to 0 to rerender a field. Set
field.isDirty_ to true instead.

Cảnh báo ở trên có nghĩa là Blockly đã phát hiện thấy bạn đang sử dụng phương thức cũ để hiển thị lại trường và muốn bạn sử dụng phương thức mới.

Để biết thêm thông tin về thuộc tính isDirty_, hãy xem isDirty_.

init

Hàm init đã được tạo thành hàm mẫu để giảm mã trùng lặp trong các lớp con.

CustomFields.UpgradeField.prototype.init = function() {
  if (this.fieldGroup_) {
    // Already initialized once.
    return;
  }

  // Call superclass.
  CustomFields.UpgradeField.superClass_.init.call(this);

  // Create DOM elements.
  this.extraDom_ = Blockly.utils.dom.createSvgElement('image',
      {
        'height': '10px',
        'width': '10px'
      });
  this.extraDom_.setAttributeNS('http://www.w3.org/1999/xlink',
      'xlink:href', 'image.svg');
  this.extraDom_.style.cursor = 'pointer';
  this.fieldGroup_.appendChild(this.extraDom_);

  // Bind events.
  this.mouseOverWrapper_ =
    Blockly.browserEvents.bind(
        this.getClickTarget_(), 'mouseover', this, this.onMouseOver_);
  this.mouseOutWrapper_ =
    Blockly.browserEvents.bind(
        this.getClickTarget_(), 'mouseout', this, this.onMouseOut_);

  // Render.
  this.setValue(this.getValue());
};

Trở thành:

CustomFields.UpgradeField.prototype.initView = function() {
  CustomFields.UpgradeField.superClass_.initView.call(this);

  this.extraDom_ = Blockly.utils.dom.createSvgElement('image',
      {
        'height': '10px',
        'width': '10px'
      });
  this.extraDom_.setAttributeNS('http://www.w3.org/1999/xlink',
      'xlink:href', 'image.svg');
  this.extraDom_.style.cursor = 'pointer';
  this.fieldGroup_.appendChild(this.extraDom_);
};

CustomFields.UpgradeField.prototype.bindEvents_ = function() {
  CustomFields.UpgradeField.superClass_.bindEvents_.call(this);

  this.mouseOverWrapper_ =
    Blockly.bindEvent_(
        this.getClickTarget_(), 'mouseover', this, this.onMouseOver_);
  this.mouseOutWrapper_ =
    Blockly.bindEvent_(
        this.getClickTarget_(), 'mouseout', this, this.onMouseOut_);
};

Tức là tính năng chặn giờ đây sẽ tự động xử lý:

  • Kiểm tra xem trường này đã được khởi tạo chưa.
  • Tạo fieldGroup_.
  • Hiển thị trường.
  • Liên kết chú giải công cụ và hiển thị sự kiện của trình chỉnh sửa.

Bạn sẽ cần xử lý:

onMouseDown_

CustomFields.UpgradeField.prototype.onMouseDown_ = function(e) {
  // ...
};

Trở thành:

CustomFields.UpgradeField.prototype.showEditor_ = function() {
  // ...
}

Bạn nên ghi đè hàm showEditor_ để xử lý các lượt nhấp chuột thay vì hàm onMouseDown_, vì điều đó cho phép hoạt động đầu vào truyền qua hệ thống cử chỉ.

Để biết thêm thông tin về người chỉnh sửa, hãy xem bài viết Trình chỉnh sửa.

setValue

Hàm setValue nay là một hàm mẫu để giảm mã trùng lặp trong các lớp con. Nếu hàm setValue của bạn chứa logic, hãy cân nhắc việc tái cấu trúc hàm đó cho phù hợp với đường dẫn xử lý giá trị được mô tả trong phần Xử lý giá trị.

text_

Bạn không nên truy cập hoặc cập nhật trực tiếp thuộc tính text_ của trường. Thay vào đó, hãy sử dụng hàm getText để truy cập văn bản mà người dùng có thể đọc được của trường và hàm setValue để cập nhật giá trị được lưu trữ của trường.

Để biết thêm thông tin về giá trị của một trường so với văn bản của trường đó, hãy xem Cấu tạo của một trường.

Nhận hỗ trợ nâng cấp

Thông tin cần cung cấp

Khi yêu cầu trợ giúp, tốt nhất bạn nên đặt những câu hỏi cụ thể:

Không nên: "Trường này có vấn đề gì?"

Cũng không nên: "Giúp tôi nâng cấp trường này".

Đề xuất: "Văn bản trường không cập nhật đúng cách".

Bạn cũng cần cung cấp tài nguyên cho những người hỗ trợ bạn. Những tệp này phải dễ sử dụng đối với người khác.

Không nên:

  • Hình ảnh mã.
  • Mã chưa hoàn chỉnh.

Đề xuất:

  • Điền vào mã trường ở định dạng văn bản.
  • Hình ảnh ảnh GIF thể hiện hành vi xấu của trường.
  • Các bước tái hiện hành vi xấu của trường.
  • Phiên bản bị chặn mà bạn đang nâng cấp.

Vị trí đăng

Đăng câu hỏi về việc nâng cấp trên diễn đàn dành cho nhà phát triển bị chặn.

Nếu chắc chắn rằng đó là vấn đề về lõi khối, bạn cũng có thể đăng vấn đề trên GitHub khối. Nếu bạn quyết định đăng vấn đề, vui lòng điền vào tất cả các thông tin được yêu cầu.