我如何在一个框架中设置一个组件来聚合来自附加到同一实体的其他组件的数据?
How can I set up a component in a-frame that aggregates data from other components attached to the same entity?
场景
我正在尝试创建一个 2 组件 'system',其中有一个主组件、aggregator
组件和多个向聚合器提供数据的子 source
组件。收到所有数据后,聚合器组件将 运行 对父实体执行某些操作。我正在使用框架 0.8.2
.
最小示例
为了以最简单的形式演示逻辑,下面是一个示例,其中 3 个子组件附加到一个实体,每个子组件通过将它们推入作为聚合器组件架构一部分的数组来将字符串传递给父组件.
这里是主组件aggregator
AFRAME.registerComponent('aggregator', {
schema: {
testarray: {type: 'array', default: []},
},
update: function(){
//to demonstrate problem
console.log(this.data.testarray)
},
})
和子组件source
AFRAME.registerComponent('source', {
dependencies: ['aggregator'],
multiple: true,
schema: {
teststring: {type: 'string', default: ''},
},
init: function(){
var string = this.data.teststring
var aggArray = this.el.getAttribute('aggregator').testarray
aggArray.push(string)
this.el.setAttribute('aggregator', 'testarray', aggArray)
},
})
这里是 HTML 来测试它
<a-scene>
<a-entity
id="aggregatortest"
source__one="teststring:testone"
source__two="teststring:testtwo"
source__three="teststring:testthree">
</a-entity>
</a-scene>
Here is a glitch(明显看不多,但如果你打开控制台,你会看到一个 'empty' 数组(实际上不是空的,但看起来是空的)。
问题
如果您 运行 或查看上面的示例,您将会看到,聚合器组件的 testarray
在更新时是 'empty'。我知道数据实际上已成功传递,就好像我在控制台中查看组件一样,我可以看到数组已更新为组件 data
中的值,但它没有更新。这是一个问题,因为如果我尝试 运行 聚合器更新中的某些功能(取决于传递的数据),它不起作用。
我做错了什么吗?我需要等待加载什么吗?还是一些内部事件?我希望每次初始化 source
组件(在本例中为 3 次)时,它都会强制更新 aggregator
组件,显然是这样,但不是以某种方式我可以使用,因为我无法在更新函数中访问更新后的架构属性。
如有任何建议,我们将不胜感激,如果有任何更多信息或真实背景会有所帮助,请告诉我。
tldr:与其获取对 testarray
的引用,不如克隆它:
var aggArray = this.el.getAttribute('aggregator').testarray.slice(0)
就像我一样here. Cloning @slice(0) was recommended by David Walsh here。
用这个简单的语句
var aggArray = this.el.getAttribute('aggregator').testarray
您获取了对 testarray
的引用。
因此,对 aggArray
的任何更改都会应用到 aggregator.testarray
。在这个 fiddle 中查看。我删除了 setAttribute
位,数组仍然有新元素。
现在,请记住,如果两个数组相同,更新甚至不会触发 - 为什么会这样,旧数据和新数据完全相同。
总之,您必须提供数组的副本/克隆 -> 更新功能才能正常工作。
场景
我正在尝试创建一个 2 组件 'system',其中有一个主组件、aggregator
组件和多个向聚合器提供数据的子 source
组件。收到所有数据后,聚合器组件将 运行 对父实体执行某些操作。我正在使用框架 0.8.2
.
最小示例
为了以最简单的形式演示逻辑,下面是一个示例,其中 3 个子组件附加到一个实体,每个子组件通过将它们推入作为聚合器组件架构一部分的数组来将字符串传递给父组件.
这里是主组件aggregator
AFRAME.registerComponent('aggregator', {
schema: {
testarray: {type: 'array', default: []},
},
update: function(){
//to demonstrate problem
console.log(this.data.testarray)
},
})
和子组件source
AFRAME.registerComponent('source', {
dependencies: ['aggregator'],
multiple: true,
schema: {
teststring: {type: 'string', default: ''},
},
init: function(){
var string = this.data.teststring
var aggArray = this.el.getAttribute('aggregator').testarray
aggArray.push(string)
this.el.setAttribute('aggregator', 'testarray', aggArray)
},
})
这里是 HTML 来测试它
<a-scene>
<a-entity
id="aggregatortest"
source__one="teststring:testone"
source__two="teststring:testtwo"
source__three="teststring:testthree">
</a-entity>
</a-scene>
Here is a glitch(明显看不多,但如果你打开控制台,你会看到一个 'empty' 数组(实际上不是空的,但看起来是空的)。
问题
如果您 运行 或查看上面的示例,您将会看到,聚合器组件的 testarray
在更新时是 'empty'。我知道数据实际上已成功传递,就好像我在控制台中查看组件一样,我可以看到数组已更新为组件 data
中的值,但它没有更新。这是一个问题,因为如果我尝试 运行 聚合器更新中的某些功能(取决于传递的数据),它不起作用。
我做错了什么吗?我需要等待加载什么吗?还是一些内部事件?我希望每次初始化 source
组件(在本例中为 3 次)时,它都会强制更新 aggregator
组件,显然是这样,但不是以某种方式我可以使用,因为我无法在更新函数中访问更新后的架构属性。
如有任何建议,我们将不胜感激,如果有任何更多信息或真实背景会有所帮助,请告诉我。
tldr:与其获取对 testarray
的引用,不如克隆它:
var aggArray = this.el.getAttribute('aggregator').testarray.slice(0)
就像我一样here. Cloning @slice(0) was recommended by David Walsh here。
用这个简单的语句
var aggArray = this.el.getAttribute('aggregator').testarray
您获取了对 testarray
的引用。
因此,对
aggArray
的任何更改都会应用到 aggregator.testarray
。在这个 fiddle 中查看。我删除了 setAttribute
位,数组仍然有新元素。
现在,请记住,如果两个数组相同,更新甚至不会触发 - 为什么会这样,旧数据和新数据完全相同。
总之,您必须提供数组的副本/克隆 -> 更新功能才能正常工作。