Các thuộc tính này cho phép các thành phần được kết nối để chúng có thể tương tác với nhau. Nguyên tắc này hơi đơn giản: nhập (lấy) một giá trị từ một thành phần khác hoặc xuất (gửi) một giá trị sang một thành phần khác hoặc thực hiện cả hai.
Lưu ý: để duy trì sự rõ ràng trong câu trả lời này, "thành phần" là một đối tượng Javascript được RequireJS trả về, có một tên cụ thể và có thể được truy cập bằng tên đó thông qua UIRegistry.
Ngoài ra, tất cả các ví dụ dưới đây sẽ nằm trong thuộc defaults: {}
tính của thành phần.
Với nguyên tắc được đặt ra, hãy bắt đầu với những gì tôi cho là khái niệm dễ nhất:
Nhập khẩu
Thuộc tính này lấy một giá trị từ một thành phần khác và gán nó cho thuộc tính được chỉ định. Trong ví dụ sau, chúng tôi khai báo nhập:
imports: {
message: '${ $.provider }:data.message'
}
Khi Magento khởi tạo thành phần này, nó sẽ cố gắng gán giá trị cho thuộc message
tính. Khách sạn này sẽ có sẵn trong bối cảnh KnockoutJS. Tuy nhiên, như chúng ta biết , nó sẽ đánh giá giá imports.message
trị dưới dạng biểu thức bằng chữ đầu tiên. Trong trường hợp này, Magento sẽ phân tích cú pháp $.provider
và sẽ nhận được một giá trị. Mặc dù đó có thể là bất kỳ số lượng nào, trong ví dụ này và theo nhiều trường hợp sử dụng cốt lõi của Magento, đó là tên của một thành phần có trong sổ đăng ký UI. Điều đó sẽ được phân tích cú pháp trước bước tiếp theo.
Vì message
tài sản là trong imports
tài sản, nó sẽ được chuyển đến setLinks()
phương thức trong uiElement.initLinks()
. Các setLinks()
phương pháp là ở Magento/Ui/view/base/web/js/lib/core/element/links.js
. Ở đó, nó lặp trên tất cả các thuộc tính (chỉ message
ở đây) trong đối tượng được truyền vào ( imports
trong trường hợp này). Trên các thuộc tính đó, nó sẽ cố gắng truyền dữ liệu từ thành phần này sang thành phần khác.
Các transfer()
chức năng là nơi quan tâm tiếp theo. Ở đây, sổ đăng ký được tìm kiếm thành phần là "chủ sở hữu", trong trường hợp nhập. Thành phần này là thành phần hiện đang "sở hữu" hoặc có dữ liệu và sẽ là $.provider
ví dụ trong ví dụ trên. Nếu thành phần được tìm thấy, sau đó nó sẽ tiến hành liên kết dữ liệu với setLink()
chức năng.
Có hai điều cần lưu ý trong phương thức đó: thứ nhất, nó đặt một trình lắng nghe sự kiện trên thuộc tính và thứ hai, nó sẽ ngay lập tức chuyển dữ liệu nếu cờ áp dụng đã được gửi. Trong thử nghiệm của tôi, nó luôn truyền immediate
tham số để chuyển xảy ra trong quá trình khởi tạo. Tuy nhiên, do trình lắng nghe sự kiện được đính kèm trong bước đầu tiên, nó sẽ tiếp tục cập nhật các giá trị, nếu chúng thay đổi, để cả hai thành phần giữ nguyên trạng thái đồng bộ.
Sau đó, dữ liệu được đặt trên (hoặc, theo thuật ngữ đơn giản hơn: "được trả về thành phần") có thuộc imports: {}
tính. Như tôi đã đề cập trước đó, sau đó nó được gán trực tiếp vào thuộc tính của thành phần đã khai báo nó - về cơ bản this.message
trong ví dụ trên và không this.defaults.imports.message
. Do đó, data-bind="text: message
sẽ hiển thị giá trị được trả về từ thuộc data.message
tính của thành phần được liên kết .
Cách tiếp cận này cho phép bạn xác định tên thuộc tính là gì trong thành phần nguồn. Trong ví dụ trên, bạn có thể sử dụng alertMessage: ...
thay vì message
làm tên thuộc tính của thành phần.
Xuất khẩu
Xuất khẩu là nghịch đảo của imports
. Chúng dựa trên chức năng tương tự như nhập khẩu, nhưng thay vì lấy dữ liệu từ một thành phần và gán nó cho chính nó, nó sẽ gửi dữ liệu của chính nó đến một thành phần khác. Kết quả là gần như mọi thứ đều ngược lại. Lấy ví dụ này:
exports: {
phoneNumber: '${ $.contactForm }:phone'
}
Trong ví dụ này, setLinks()
lấy giá trị của thuộc tính của thành phần phoneNumber
này và gán nó cho thuộc phone
tính của biểu mẫu liên hệ . Nó giống như tuyên bố rõ ràng một phone
thuộc tính trong $.contactForm
thành phần. Nếu không có bất kỳ thiết lập cụ thể nào trong $.contactForm
, bạn có thể truy cập trực tiếp dữ liệu này. Có lẽ như thế này trong một mẫu Knockout : data-bind="text: phone
.
Liên kết
Cuối cùng, links
tài sản giống như khai báo cả imports
và exports
cho cùng một tài sản. Thoạt nhìn, điều này có vẻ giống như một tài liệu tham khảo tròn. Trong khi đó là theo một cách nào đó, có những lúc điều này có thể hữu ích. Mặc dù tôi chắc chắn có nhiều trường hợp sử dụng hơn, nhưng trường hợp tôi có thể thấy là khả năng một thành phần có thể thao tác dữ liệu từ một thành phần khác một cách linh hoạt. Trong trường hợp này, ElementA là nguồn của một số dữ liệu và hiển thị dữ liệu đó trên trang. Thành phần cần phải thao tác dữ liệu đó và vì vậy nó thuộc links
tính đó. Nó có thể vừa hiển thị dữ liệu vừa thao tác dữ liệu thực tế trong Thành phần mà không bao giờ mở rộng hoặc thay đổi Thành phần.
Tuy nhiên, một điều cần lưu ý là, theo mặc định, links
không phải là một cách để kết nối hai mô-đun khác. Nói cách khác, Thành phần không thể link
thành phầnA thành Thành phầnB. Nó là một phương pháp đồng bộ hai chiều với một thành phần khác.
Liên kết ( imports
, exports
và links
) hầu như luôn có thể tạo điều kiện cho các chức năng được gán cho các thuộc tính đó. Tôi gặp phải một số hành vi kỳ lạ trong khi tạo ra các vật thể quan sát và sử dụng links
nhưng nhìn chung nó hoạt động khá tốt.
Liên kết cung cấp các giá trị có sẵn trong phạm vi KnockoutJS và có thể được thao tác như bất kỳ thuộc tính nào khác. Và, để nhắc lại rõ ràng: hãy nhớ rằng imports
, exports
và links
đối tượng của các phím luôn luôn đề cập đến tính chất của các thành phần hiện tại (mà trong đó các thuộc tính đã được tuyên bố), trong khi gắn liền giá trị cho tên và thuộc tính của các thành phần từ xa .
Tóm lại, Magento sử dụng chức năng liên kết này để kết nối các thành phần khác nhau với nhau và đó là cách chúng ta có thể truy cập, cung cấp hoặc đồng bộ hóa dữ liệu với các thành phần khác.