Эти свойства позволяют компонентам соединяться, чтобы они могли взаимодействовать друг с другом. Принцип несколько прост: импортировать (принимать) значение из другого компонента или экспортировать (отправлять) значение в другой компонент, или делать то и другое.
Примечание: для ясности в этом ответе «компонент» - это объект Javascript, который возвращается RequireJS, имеет определенное имя и может быть доступен по этому имени через UIRegistry.
Кроме того, все приведенные ниже примеры будут находиться внутри defaults: {}
свойства компонента.
С изложенным принципом давайте начнем с того, что я считаю самой простой концепцией:
импорт
Это свойство берет значение из другого компонента и присваивает его указанному свойству. В следующем примере мы объявляем импорт:
imports: {
message: '${ $.provider }:data.message'
}
Когда Magento инициализирует этот компонент, он попытается присвоить значение message
свойству. Это свойство будет доступно в контексте KnockoutJS. Однако, как мы знаем , он imports.message
сначала оценит значение как буквенное выражение шаблона. В этом случае Magento проанализирует $.provider
и должен получить значение. Хотя это может быть любое количество вещей, в этом примере и согласно многим основным сценариям использования Magento, это имя компонента, которое находится в реестре пользовательского интерфейса. Это будет проанализировано до следующего шага.
Поскольку message
свойство находится в imports
свойстве, оно будет передано setLinks()
методу в uiElement.initLinks()
. setLinks()
Метод в Magento/Ui/view/base/web/js/lib/core/element/links.js
. Там он перебирает все свойства (только message
здесь) в объекте, который был передан ( imports
в данном случае). На этих свойствах он будет пытаться передать данные из одного компонента в другой.
transfer()
Функция является следующим местом интереса. Здесь в реестре выполняется поиск компонента, который является «владельцем», в случае импорта. Этот компонент является тем, который в настоящее время «владеет» или имеет данные и будет $.provider
в приведенном выше примере. Если компонент найден, он продолжит связывать данные с setLink()
функцией.
В этом методе есть две вещи, которые следует отметить: во-первых, он устанавливает прослушиватель событий для свойства, а во-вторых, он немедленно передает данные, если был отправлен соответствующий флаг. В моем тестировании всегда передавался immediate
параметр, поэтому передача происходила во время инициализации. Однако из-за прослушивателя событий, который был присоединен на первом шаге, он продолжит обновлять значения, если они изменятся, так что оба компонента будут синхронизированы.
Затем данные устанавливаются на (или, проще говоря: «возвращено») компоненту, у которого было imports: {}
свойство. Как я упоминал ранее, он затем присваивается непосредственно объявленному свойству компонента - по существу, this.message
в приведенном выше примере, а не так this.defaults.imports.message
. В результате data-bind="text: message
должно отображаться значение, возвращаемое из data.message
свойства связанного компонента .
Этот подход позволяет определить, какое имя свойства содержится в исходном компоненте. В приведенном выше примере вы можете использовать alertMessage: ...
вместо имени message
свойства вашего компонента.
экспорт
Экспорт обратный imports
. Они основаны на той же функциональности, что и импорт, но вместо того, чтобы брать данные из одного компонента и присваивать его себе, он отправляет свои данные другому компоненту. В результате почти все наоборот. Возьмите этот пример:
exports: {
phoneNumber: '${ $.contactForm }:phone'
}
В этом примере setLinks()
принимает значение свойства этого компонентаphoneNumber
и присваивает его phone
свойству формы контакта . Это то же самое, что явно объявить phone
свойство в $.contactForm
компоненте. Без какой-либо конкретной настройки в $.contactForm
, вы можете получить доступ к этим данным напрямую. Возможно, так в шаблоне нокаута data-bind="text: phone
.
связи
Наконец, links
свойство такое же, как объявление обоих imports
и exports
для одного и того же свойства. На первый взгляд это может показаться круговой ссылкой. Хотя в некотором смысле это может быть полезным. Хотя я уверен, что есть еще много вариантов использования, я вижу, что один компонент может динамически манипулировать данными из другого компонента. В этом случае ComponentA является источником некоторых данных и отображает их на странице. Компонент B должен манипулировать этими данными и таким образом обращаться links
к этому свойству. Он может как отображать данные, так и манипулировать фактическими данными в ComponentA, не расширяя и не изменяя ComponentA.
Однако следует отметить, что по умолчанию links
это не способ соединения двух других модулей. Другими словами, ComponentC не может от link
ComponentA до ComponentB. Это метод двунаправленной синхронизации одного компонента с другим.
Связывание ( imports
, exports
и links
) почти всегда может облегчить функции , возложенные на эти свойства , а также. Я столкнулся с каким-то странным поведением, создавая наблюдаемые и используя, links
но в целом это работало довольно хорошо.
Связывание предоставляет значения, которые доступны в области действия KnockoutJS и могут управляться так же, как и любое другое свойство. И, чтобы подтвердить ясно: помните , что imports
, exports
и links
объект ключи всегда относятся к свойствам компонента тока (тот , в котором были объявлены эти свойства), в то время как значение относится к имени и свойствам удаленного компонента .
В заключение, Magento использует эту функциональность связывания для соединения различных компонентов друг с другом, и это способ, которым мы можем получить доступ, предоставить или синхронизировать данные с другими компонентами.