Angular2 GWT集成时出现意外的指令值错误

时间:2016-03-18 12:28:02

标签: javascript gwt angular

我试图在GWT 2.6.0

中使用Angular2(只有JavaScript,没有TypeScript)

有一个非常基本的代码:

public native void init() /*-{
  var MyComp= $wnd.ng.Component({
  selector: 'my-sample',
  properties:['model']
  })
  .View({
  directives: [], 
  template: '\n<h1>Hello world!</h1>'
  })
  .Class({
    constructor: function() {
    }
  });
  var MyApp= $wnd.ng.Component({selector:'my-app'})
  .View({
    directives: [MyComp],
    template:'<my-sample></my-sample>'
  })
  .Class({
    constructor:function(){}
  });
  $wnd.setTimeout(function() { $wnd.ng.bootstrap(MyApp);}, 1000);
}-*/;

但&lt; my-sample&gt;&lt; / my-sample&gt;在我的模板中导致此错误:

angular2.sfx.dev.js:33004 EXCEPTION: Unexpected directive value 'function (){' on the View of component 'function (){'System.register.BrowserDomAdapter.logError @ angular2.sfx.dev.js:33004System.register.BrowserDomAdapter.logGroup @ angular2.sfx.dev.js:33015System.register.ExceptionHandler.call @ angular2.sfx.dev.js:4792(anonymous function) @ angular2.sfx.dev.js:28798System.register.NgZone._onError @ angular2.sfx.dev.js:11072System.register.NgZone._createInnerZone.errorHandling.onError @ angular2.sfx.dev.js:10991run @ angular2.sfx.dev.js:141System.register.NgZone._createInnerZone.zone.fork.fork.$run @ angular2.sfx.dev.js:11005zoneBoundFn @ angular2.sfx.dev.js:111lib$es6$promise$$internal$$tryCatch @ angular2.sfx.dev.js:1507lib$es6$promise$$internal$$invokeCallback @ angular2.sfx.dev.js:1519lib$es6$promise$$internal$$publish @ angular2.sfx.dev.js:1490(anonymous function) @ angular2.sfx.dev.js:219System.register.NgZone._createInnerZone.zone.fork.fork.$scheduleMicrotask.microtask @ angular2.sfx.dev.js:11031run @ angular2.sfx.dev.js:138System.register.NgZone._createInnerZone.zone.fork.fork.$run @ angular2.sfx.dev.js:11005zoneBoundFn @ angular2.sfx.dev.js:111lib$es6$promise$asap$$flush @ angular2.sfx.dev.js:1301
angular2.sfx.dev.js:33004 STACKTRACE:System.register.BrowserDomAdapter.logError @ angular2.sfx.dev.js:33004System.register.ExceptionHandler.call @ angular2.sfx.dev.js:4794(anonymous function) @ angular2.sfx.dev.js:28798System.register.NgZone._onError @ angular2.sfx.dev.js:11072System.register.NgZone._createInnerZone.errorHandling.onError @ angular2.sfx.dev.js:10991run @ angular2.sfx.dev.js:141System.register.NgZone._createInnerZone.zone.fork.fork.$run @ angular2.sfx.dev.js:11005zoneBoundFn @ angular2.sfx.dev.js:111lib$es6$promise$$internal$$tryCatch @ angular2.sfx.dev.js:1507lib$es6$promise$$internal$$invokeCallback @ angular2.sfx.dev.js:1519lib$es6$promise$$internal$$publish @ angular2.sfx.dev.js:1490(anonymous function) @ angular2.sfx.dev.js:219System.register.NgZone._createInnerZone.zone.fork.fork.$scheduleMicrotask.microtask @ angular2.sfx.dev.js:11031run @ angular2.sfx.dev.js:138System.register.NgZone._createInnerZone.zone.fork.fork.$run @ angular2.sfx.dev.js:11005zoneBoundFn @ angular2.sfx.dev.js:111lib$es6$promise$asap$$flush @ angular2.sfx.dev.js:1301
angular2.sfx.dev.js:33004 Error: Unexpected directive value 'function (){' on the View of component 'function (){'
    at new BaseException (http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:25289:21)
    at RuntimeMetadataResolver.System.register.RuntimeMetadataResolver.getViewDirectivesMetadata (http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:13091:17)
    at RuntimeCommandFactory.componentTemplateFactory (http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:36943:66)
    at RuntimeCommandFactory.System.register.RuntimeCommandFactory.createBeginComponent (http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:12451:33)
    at CommandBuilderVisitor.System.register.CommandBuilderVisitor.visitElement (http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:12572:46)
    at ElementAst.System.register.ElementAst.visit (http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:11797:22)
    at http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:11876:27
    at Array.forEach (native)
    at Object.templateVisitAll (http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:11875:10)
    at CommandCompiler.System.register.CommandCompiler.compileComponentRuntime (http://127.0.0.1:8888/angular2demo/angular2.sfx.dev.js:12400:22)

我刚刚取出本机代码并粘贴在非GWT应用程序HTML文件脚本标签中(只需将$ wnd替换为窗口),一切正常。

这个错误是什么以及如何解决?

2016年3月22日 在Eric的回复之后,我尝试使用UMD捆绑包,现在在GWT中生成这样的代码。

public native void init() /*-{
    if (!$wnd.SampleApp)
        $wnd.SampleApp = {}
    $wnd.SampleApp.SampleComponent =
      $wnd.ng.core.Component({
          selector: 'my-sample',
    template: '\n<h1>Hello world!</h1>'
          })
          .Class({
            constructor: function() {}
          });
    $wnd.SampleApp.Main =
    $wnd.ng.core.Component({
        selector: 'my-app',
        directives: [$wnd.SampleApp.SampleComponent],
        template: '<h1>My First Angular 2 App</h1>'
    })
    .Class({
    constructor: function() {}
    });
    setTimeout(function() {
        $wnd.ng.platform.browser.bootstrap($wnd.SampleApp.Main);
    }, 3000);
}-*/;

但它仍然给出错误:

EXCEPTION: Unexpected directive value 'class0' on the View of component 'class1'
browser_adapter.ts:73 EXCEPTION: Unexpected directive value 'class0' on the View of component 'class1'BrowserDomAdapter.logError @ browser_adapter.ts:73BrowserDomAdapter.logGroup @ browser_adapter.ts:84ExceptionHandler.call @ exception_handler.ts:49(anonymous function) @ application_ref.ts:262NgZone._notifyOnError @ ng_zone.ts:453collection_1.StringMapWrapper.merge.onError @ ng_zone.ts:352Zone.run @ angular2-polyfills.js:1247(anonymous function) @ ng_zone.ts:370zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:468lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:480lib$es6$promise$$internal$$publish @ angular2-polyfills.js:451(anonymous function) @ angular2-polyfills.js:123microtask @ ng_zone.ts:409Zone.run @ angular2-polyfills.js:1243(anonymous function) @ ng_zone.ts:370zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$asap$$flush @ angular2-polyfills.js:262
browser_adapter.ts:73 STACKTRACE:BrowserDomAdapter.logError @ browser_adapter.ts:73ExceptionHandler.call @ exception_handler.ts:52(anonymous function) @ application_ref.ts:262NgZone._notifyOnError @ ng_zone.ts:453collection_1.StringMapWrapper.merge.onError @ ng_zone.ts:352Zone.run @ angular2-polyfills.js:1247(anonymous function) @ ng_zone.ts:370zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:468lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:480lib$es6$promise$$internal$$publish @ angular2-polyfills.js:451(anonymous function) @ angular2-polyfills.js:123microtask @ ng_zone.ts:409Zone.run @ angular2-polyfills.js:1243(anonymous function) @ ng_zone.ts:370zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$asap$$flush @ angular2-polyfills.js:262
browser_adapter.ts:73 Error: Unexpected directive value 'class0' on the View of component 'class1'
    at new BaseException (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:4377:24)
    at RuntimeMetadataResolver.getViewDirectivesMetadata (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:26882:24)
    at TemplateCompiler._compileNestedComponentRuntime (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:21535:66)
    at http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:21520:88
    at Array.forEach (native)
    at Array.forEach (http://127.0.0.1:8888/angular2demo/es6-shim.min.js:10:16878)
    at http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:21520:44
    at Zone.run (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:1243:24)
    at Zone.run (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:13235:43)
    at zoneBoundFn (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:1220:26)

-----async gap-----
Error
    at _getStacktraceWithUncaughtError (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:2236:29)
    at Zone.fork (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:2285:47)
    at Zone.bind (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:1218:53)
    at bindArguments (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:1401:36)
    at lib$es6$promise$promise$$Promise.obj.(anonymous function) [as then] (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:1413:46)
    at TemplateCompiler._compileComponentRuntime (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:21514:19)
    at TemplateCompiler.compileHostComponentRuntime (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:21465:19)
    at RuntimeCompiler_.compileInHost (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:21366:40)
    at DynamicComponentLoader_.loadAsRoot (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:13658:32)
    at di_1.provide.useFactory (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:12500:48)

-----async gap-----
Error
    at _getStacktraceWithUncaughtError (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:2236:29)
    at Zone.fork (http://127.0.0.1:8888/angular2demo/angular2-polyfills.js:2285:47)
    at NgZone._createInnerZone (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:13223:15)
    at new NgZone (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:13009:37)
    at createNgZone (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:12523:13)
    at PlatformRef_.application (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:12624:34)
    at Object.bootstrap (http://127.0.0.1:8888/angular2demo/angular2-all.umd.dev.js:27196:65)
    at angular2demo-0.js:123:30BrowserDomAdapter.logError @ browser_adapter.ts:73ExceptionHandler.call @ exception_handler.ts:53(anonymous function) @ application_ref.ts:262NgZone._notifyOnError @ ng_zone.ts:453collection_1.StringMapWrapper.merge.onError @ ng_zone.ts:352Zone.run @ angular2-polyfills.js:1247(anonymous function) @ ng_zone.ts:370zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:468lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:480lib$es6$promise$$internal$$publish @ angular2-polyfills.js:451(anonymous function) @ angular2-polyfills.js:123microtask @ ng_zone.ts:409Zone.run @ angular2-polyfills.js:1243(anonymous function) @ ng_zone.ts:370zoneBoundFn @ angular2-polyfills.js:1220lib$es6$promise$asap$$flush @ angular2-polyfills.js:262

再次,如果我把这个代码拿出来放在HTML文件的脚本块中,它就可以了。因此在GWT中运行时发生了错误。 GWT代码涉及编译步骤,所以我担心我无法为它创建一个plnkr。

2 个答案:

答案 0 :(得分:0)

我希望GWT 2.6.0不是您的要求。如果您可以切换到GWT 2.8.0(还支持Java 8),还有另一种解决方案。 您是否尝试使用angular2-gwt(http://lteconsulting.fr/angular2boot/)? 以下是Angular2Boot应用程序示例:https://github.com/ltearno/angular2-gwt。我猜你也可以在没有Spring后端的情况下使用这个库。

PS:当前的GWT方法建议使用JsInterop而不是JNI。

答案 1 :(得分:0)

我能够以一种相当难以令人信服的方式解决它。对于构造函数,我不得不调用外部JavaScript文件来获取函数,而不是仅仅在JSNI中定义它们。

声明如下:

  constructor: function() {}
由于某些不兼容性,

导致此类错误。

我用以下内容替换它:

  constructor: $wnd.wrapFunction4GWT(function() {})

其中包装函数将返回一个新函数,该函数继承GWT本机层中定义的函数(因为该函数不会像这样实时地为空)。