属性的循环引用,和属性的延迟定义
https://docs.cocos.com/creator/manual/zh/scripting/reference/class.html#属性延迟定义 如果两个类相互引用,脚本加载阶段就会出现循环引用,循环引用将导致脚本加载出错。 循环引用时 type 就会变为 undefined。 解决方案是通过箭头函数延迟初始化,具体js-es5方案参考官方文档。
ts版本下的表现形式
代码部分(无报错):
// A.ts
import { B } from "./B";
const { ccclass, property } = cc._decorator;
@ccclass
export class A extends cc.Component {
@property(B)
x: B = null
}
// B.ts
import { A } from "./A";
const { ccclass, property } = cc._decorator;
@ccclass
export class B extends cc.Component {
@property(A)
x: A = null
}
编辑器中:
特别说明:
在ts中,import
语句是没有循环引用问题的,因为import
输出的是一个值的引用,只有在具体使用时才会去取值,在这篇文章中有更具体的描述http://es6.ruanyifeng.com/#docs/module-loader#ES6-模块与-CommonJS-模块的差异。
但是通过@property()
定义的属性,是直接通过编辑器初始化的,相当于直接使用了,则会造成循环引用的问题。
2种前置的处理方案
设计好的分层,避免循环引用
这个就不多说了,需要很多的积累,对现有的没什么问题没什么直接作用。
传入cc.Node
,在onLoad()
中实现属性的延迟定义
这个方法就比较简单了,逻辑也比较顺畅,很适合新手去使用,实现方案如下所示:
import { A } from "./A";
const { ccclass, property } = cc._decorator;
@ccclass
export class B extends cc.Component {
@property(cc.Node)
x: A = null
onLoad() {
this.x = this.x.getComponent(A)
}
}
第3种方案,通过箭头函数实现属性的延迟定义
传入cc.Node
这种方案虽然逻辑简单,但是写起来不好看,还需要在onLoad()
中初始化,容易漏。
1个下午之后……我放弃了,不行,还是等官方更新吧。ts无法实现箭头函数化的属性延迟定义。埋个坑。