属性的循环引用,和属性的延迟定义

https://docs.cocos.com/creator/manual/zh/scripting/reference/class.html#属性延迟定义 如果两个类相互引用,脚本加载阶段就会出现循环引用,循环引用将导致脚本加载出错。 循环引用时 type 就会变为 undefined。 解决方案是通过箭头函数延迟初始化,具体js-es5方案参考官方文档。

ts版本下的表现形式

代码部分(无报错):

  1. // A.ts
  2. import { B } from "./B";
  3. const { ccclass, property } = cc._decorator;
  4. @ccclass
  5. export class A extends cc.Component {
  6. @property(B)
  7. x: B = null
  8. }
  9. // B.ts
  10. import { A } from "./A";
  11. const { ccclass, property } = cc._decorator;
  12. @ccclass
  13. export class B extends cc.Component {
  14. @property(A)
  15. x: A = null
  16. }

编辑器中:

delay-define-creator.png

特别说明:

在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无法实现箭头函数化的属性延迟定义。埋个坑。