拜托官方抽空改个大BUG

给Creator的官方大大们提供一个大BUG:关于Creator中CCClass.js中的一段代码:

function CCClass(options) {
options = options || {};
var name = options.name;
var base = options.extends;
var mixins = options.mixins;
var cls = define(name, base, mixins, options);
name || (name = cc.js.getClassName(cls));
cls._sealed = true;
base && (base._sealed = false);
var properties = options.properties;

问题代码:上面加粗的代码。
问题描述:当项目使用TS来实现类的继承时,这里的_sealed值一直为true,导致在调用GetComponet时,如果传入的参数是类的基类名称,那么就无法get到子类的组件对象。 当使用JS原生来实现时,是OK的。

而我的代码中对整个UI这块做了封装,有太多需求需要通过传入基类的名称去GET组件对象,现在就卡在这里。

  1. 我先在浏览器平台解决这个问题:不论我怎么改CCClass.js中的这处代码(强制改为false, 然后把第二句去掉),都不管用,然后找到了/Applications/CocosCreator.app/Contents/Resources/engine/bin/cocos2d-js-for-preview.js,改这里面的对应代码,然后浏览器平台就能在调试状态下执行正常,但在发布出来的文件中,还是错的,代码是s._sealed=!0; base?(s._sealed=!1); 最后解决办法还是直接改发布后的这个文件中的这块代码。

  2. 在模拟器上,无论我改哪里都不OK,始终没有正确执行。

也许是因为我对cocos构建发布的流程不太熟悉,没找到准确的位置,但是这个编辑器也确实是有问题的:无论我在设置里面敲定使用内置引擎还是使用自定义的引擎,构建时都会使用我没改过的代码,这就迷茫了,不知道到底它用的代码在哪。希望官方能抽点空闲来帮大家梳理一下关于构建这块的具体流程,使用的引擎到底 有什么潜规则,不然这样做起来很打击开发者信心。官方不解决,我们自己也没办法弄才真是让人失望!

1赞

你试下修改这几个文件看看
引擎浏览器预览: engine\bin\cocos2d-js-for-preview.js
引擎模拟器预览: engine\bin\jsb_polyfill-for-preview.js
构建android项目调试模式: engine/bin/.cache/android/jsb_polyfill.dev.js
构建android项目非调试模式: engine/bin/.cache/android/jsb_polyfill.js
若engine/bin/.cache/android 下无 jsb_polyfill.dev.js、jsb_polyfill.js
文件构建时将根据若engine/cocos2d重新编译 出 jsb_polyfill.dev.js、jsb_polyfill.js
构建web项目调试模式: cocos2d-js.js
构建web项目非调试模式: cocos2d-js-min.js

1赞

非常感谢你的回答,确实,你的提议能解决这个问题。但是一旦重新构建生成后有问题的文件还是会覆盖修改过的文件,还得重新手动改这些文件。

为什么更改了源码ccclass.js,都不能保证重新编译出来的 jsb_polyfill.dev.js、jsb_polyfill.js 这两个文件中的代码一起变更 ,难道这些文件中的代码来源不是ccclass.js?

1赞

看了你的描述,目测你使用的 1.x 版本的引擎,建议到官方仓库下的 readme 中研究一下,配置好你电脑的环境,使用命令行将你修改的引擎部分重新生成。
https://github.com/cocos-creator/engine

好的谢谢。

谢谢反馈,这个问题是挺严重的,我们会尽量修复。

我这边试了下,getComponent 是可以通过父类获取到子类组件的,
不知道你是怎么使用的,可以提供下你的 demo 吗

使用TS来写类的继承。

ts 是没问题的,可以提供下你的 demo ,讲下具体怎么操作的吗?

我用3.0也遇到这个问题,后面发现需要加上 @ccclass, _seal才会设置成false,从而通过instanceof来判断