uiElement对象中的“导入/导出”默认值是什么?


8

在许多Magento 2的UI元素视图模型构造函数中,defaults数组将具有importsexports属性。

return Collection.extend({
    defaults: {
        //...
        imports: {
            rows: '${ $.provider }:data.items'
        },

return Insert.extend({
    defaults: {
        //...
        exports: {
            externalFiltersModifier: '${ $.externalProvider }:params.filters_modifier'
        },

看一下uiElement模块的来源,

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
    initLinks: function () {
        return this.setListeners(this.listens)
                   .setLinks(this.links, 'imports')
                   .setLinks(this.links, 'exports')
                   .setLinks(this.exports, 'exports')
                   .setLinks(this.imports, 'imports');
    },

实例化对象时,这些导入/导出似乎与对象之间的“链接”信息有关。但是,尚不清楚此链接如何工作(基于uiRegistry?)或类似字符串的语法是什么${ $.provider }:data.items。显然,这些字符串使用的模板文字扩展为类似

foo_bar:data.items

但是,最后一个字符串的含义仍然很神秘。

有谁知道这些对象的导入/导出属性如何工作?


不会发布一个答案,因为我还没有实际使用他们,但devdocs多加一点启示:devdocs.magento.com/guides/v2.1/ui-components/...
威奈

Answers:


21

这些属性允许连接组件,以便它们可以彼此交互。原理有点简单:从另一个组件导入(获取)值或导出(发送)到另一个组件,或同时执行两个操作。


注意:为了保持答案的清晰性,“组件”是RequireJS返回的Javascript对象,具有特定名称,可以通过UIRegistry使用该名称进行访问。

此外,下面的所有示例都将在组件的defaults: {}属性内。


有了原则,让我们从我认为最简单的概念开始:

进口货

该属性从另一个组件获取一个值,并将其分配给指定的属性。在以下示例中,我们声明一个导入:

imports: {
    message: '${ $.provider }:data.message'
}

Magento初始化此组件时,它将尝试将值分配给message属性。该属性将在KnockoutJS上下文中可用。但是,众所周知,它将首先将该imports.message值作为模板文字表达式求值。在这种情况下,Magento将解析$.provider并应获取一个值。尽管可能有很多事情,但在此示例中,根据Magento的许多核心用例,它是UI注册表中组件的名称。将在下一步之前对其进行解析。

由于该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属性是一样的声明都importsexports同一属性。乍一看,这似乎是一个循环参考。尽管这是某种方式,但有时这可能会有所帮助。虽然我确定还有更多的用例,但我可以看到的是一个组件能够动态地操作来自另一个组件的数据的能力。在这种情况下,ComponentA是某些数据的源并将其显示在页面上。ComponentB需要操纵该数据,并因此使其links具有该属性。它既可以显示数据也可以在ComponentA中操作实际数据,而无需扩展或更改ComponentA。

但是要注意的一件事是,默认情况下,links这不是连接其他两个模块的方法。换句话说,ComponentC不能从linkComponentA到ComponentB。这是一种将一个组件与另一个组件双向同步的方法。


链接(importsexportslinks)几乎总是可以使分配给这些属性的功能也变得容易。在创建可观察对象和使用links该对象时,我遇到了一些奇怪的行为,但总的来说,它工作得很好。

链接提供的值在KnockoutJS范围内可用,并且可以像对待其他任何属性一样进行操纵。而且,重申明确:记住importsexportslinks对象的钥匙始终参考的性质电流分量(在这些属性被宣布的),而值有关的名称和属性远程组件


总之,Magento使用此链接功能将不同的组件彼此连接,这是我们可以访问,提供数据或与其他组件同步数据的一种方式。


很棒的解释@ bassplayer7-您有这个例子吗?我了解它是如何工作的,但是对我而言,我无法让我的两个简单UI组件共享可观察到的KO。
本·克鲁克

@BenCrook,不幸的是,我已经有一段时间没有做太多事情了,所以我没有一个合适的选择。到现在为止,我确定您已经弄清楚了,但是我建议您使用importsexports而不是links。我发现links它更加晦涩难懂。如果您确实遇到过示例,可以共享一个链接吗?
bassplayer7

我尝试并无法使导入/导出/链接正常运行,Vinai在这里回答了这个问题尽管我还没有机会进行尝试。
本·克鲁克

在官方开发文档中,此信息非常有用。UI Cpponent过程只是一个可怕的野兽。
纳撒尼尔·罗杰斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.