循环引用这个报错太恶心了

?? 显然是你记错了. 而且 import type 解决了类型提示的问题.


// manager.ts

import type {Item} from './item';
export const ITEM_COMP = 'xxx';

@ccclass
export class Manager extends Component
{
  some_method()
  {
     (<Item> this.node.children[0].getComponent(ITEM_COMP)).foo();
  }
}

// item.ts

import {ITEM_COMP, Manager} from './manager';

@ccclass(ITEM_COMP)
export class Item extends Component 
{
    foo() { Manager.instance.bar() } 
}

为啥你一直推荐用 import type? 每个方法都有合适和不合适的使用时机

用字符串作为 getCompoent 参数是给项目增加隐患,类名改了就获取不到,只有运行时才知道错误,而一些不常用的模块如果测试没测到就是隐藏 bug

你这纯粹是为了 import type 而 import type,根本没思考哪种更适合

首先, COMP_NAME 是一个 export const, 又不是 Magic string. 完全不影响重构和维护.
要说有什么缺点, 大概是重名冲突 (稍大的项目肯定是要加前缀的, 如 ‘cc.Button’, ‘cc.Label’ … )

其次, 编辑器只认 @ccclass(’ 里面的内容’), 根本不管你类名是什么 (如果 @ccclass(空), 编辑器认 文件名).

对~ 因为 getComponent(COMP_NAME) 根本不是问题.
typescript 支持 import type 很大程度就是为了解决循环引用问题, 简单容易理解, why not ?


总结

  • dynamic import: 把模块作为 延迟导入使用
  • import type: 只导入 ts 类型, 不产生运行时开销
  • 它们不是对立关系

你怕是自动忽略了什么,而且提出使用字符串来使用 getComponent 的,大部分都是新手所为

COMP_NAME 只是规避循环引用的一种办法而已, 它不影响你在别处直接用类名.
如果你很多地方都有循环引用, 所以觉得这是个问题, 那才是真的问题.

你怕是自动忽略了什么, 有什么绝对好与坏的东西么, 事实上, 引擎代码里就有不少 getComponent(“string”).

别强撑面子了

1. 我刚说完有合适不合适的

getComponent 使用字符串和类型对象的参数傻子都知道选什么

2. 自我矛盾

我说类名的确是不具体,我指的也是这个意思

1. 你能保证不修改 ccclass 装饰器参数传递的类型名?或者文件名?

2. 你能保证团队里的每个人都会在修改后去检查是否有使用 getComponent 接口(参数为字符串)获取这个类型并修改吗?

最后不管有没有循环引用,都应该避免使用字符串参数使用 getComponent,这才是我的想法

在我提醒后还没理解,属实把我给整笑了

论坛里面一堆为了面子能指鹿为马的,笑死了,承认自己错误像要杀了自己一样

来了, 来了, 他来了… 为什么论坛里的人都讨厌你, 没点数么?


回到正题:

?? 随便改啊, 会有问题 ? COMP_NAME 又不是魔法字符串, 明白么?
而且, 只有 mgr 里面需要 getComponent(COMP_NAME), 其他地方谁不让你用 getComponent(Item) 了么?

import {COMP_NAME} from ‘mgr’;

@cclass(COMP_NAME)
class Item {}


初衷没错, 为了容易维护, 少用魔法字符串.
可惜咱 不是魔法字符串 …只要没有违背你的初衷, 何必去坚持那些教条?

比较一下:

  • export const STRING = ‘xxx’;
  • export const CLASS = class {}

本质上是一样的. 只是一个是 ‘string’, 一个是 ‘function’,
你凭什么规定 ‘function’ 一定比 ‘string’ 更好 ?

只是对于 typescript 来说, 用 getComponent(class) 要 方便一点, 仅此而已.

咋到你这里还成了正治正确了? 还让别人 “认错”… 能不能不要这么幼稚?


还有一种情况, 也适合用 getComponent(string):

编译时剔除 (与 cc 引擎相似), 我们这样可以检测它是否存在, 有条件地决定一些 feature, 而不用 import 那个组件, 避免因此导致无法剔除, 或者变成 undefined:

//如果你剔除了 Button, 它就是 undefined 了, 你甚至无法确定是不是 bug...
//❌ error: getComponent: Type must be non-nil
this.getComponent(Button); 
//但你可以用:
this.getComponent('cc.Button') 

接下来 :rofl: :rofl:

事实上,觉得我说的对的人不会回复,而只有被我说中恼羞成怒的人才会一直回复导致你的印象是

又来 无中生有

请引用一下我的规定 ‘function’ 一定比 ‘string’ 更好

我之所以说为什么 getComponent 使用类型对象参数比字符串参数好,我上面已经说了,恼羞成怒的人自然不会看到,所以一直忽略我说的话

甚至为了合理而合理

我请问下正常人有几个会把项目里面所有 ccclass 装饰器字符串参数全部包装起来使用?

  • 包装
  • 未包装

0 投票者

自己诠释了什么叫无中生有. 谁跟你说过所有地方都这样写 ??

好的,既然不是所有地方,那么你是否承认使用 getComponent 字符串参数比类型对象参数维护困难? :rofl:

@ccclass(COMP_NAME) 请实例演示下如何就获取不到了.

前面没看懂我说的, 后面假模假样说自己 “也是这个意思” …真有意思.

“都应该” ? 我上面说了有的情形字符串更好, 这会儿装没看见?

你说的字符串维护困难的原因, 都是自以为是, 我 demo 是这么写的么?

我的 demo 一开始写法就没变, 单纯作为规避循环引用. 正常人会认为所有代码都这样写?

要按你的错误理解来维护, 肯定困难…

正常人用字符串: export const COMP_NAME = 'xxx'; 完事.

vs.

你用字符串: (自己说的)

  • 改个类名都要找到团队每个人所有的 getComponent, 确实困难.

  • 还打算把所有类改写成 @cclass(COMP_NAME), 勇气可嘉.


:arrow_up: 看出来了, 我说用来解决循环引用, 敢情你整个项目全是循环引用, 真是写得一手好代码 :+1:.

:arrow_up: 正常人谁需要干这些事, 没办法, 有人喜欢强行找茬呗.

你说话都会经脑子, 不然你的言论怎么这么水.

建议引用我上面写的 “维护, 肯定困难”, 来证明我前后矛盾~ 毕竟歪曲事实你比较擅长.

不然请拿出实际论据来反驳.

再说一遍我的观点:
需要的时候用 getComponent(COMP_NAME) 没有任何问题, 觉得维护困难是用得不对. (也可能是故意找茬)

破相了,开始胡搅蛮缠了 :rofl: :rofl:

自己刚说完的话马上否认

另外不要把自己想的太高,以为谁都不懂组件名是 ccclass 装饰器的参数,只是我习惯这样说而已,下面这篇帖子可以证明你的脑子是不是自视甚高

发现楼上的讨论激烈的两位, Markdown用的好棒

哈哈哈哈哈

有马赛克的地方就有技术
也有江湖 :14: