Open rstpv opened 8 years ago
Hello,
Same problem here:
Error: Error encountered resolving symbol values statically. Calling function 'PolymerElement', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function
Any solution? Thanks
It would be really good to know if there is an alternative that will be provided
I get the same message like @DanielGarciaMandillo As far as i understood the i18n of ng2, AOT will be required to compile apps with multiple languages.
I spent the last couple of days playing with this, and the only way that I could come up with was to generate source code for each element ahead of time.
For instance, write a base class that looks something like this: export class ChangeEventsAdapterDirective {
protected _eventNameForProperty = (property: string) => `${property}Change`;
constructor(props: string[]) {
props
.forEach(property => this[property] = new EventEmitter<any>(false));
}
_emitChangeEvent(property: string, event: any) {
// Event is a notification for a sub-property when `path` exists and the
// event.detail.value holds a value for a sub-property.
// For sub-property changes we don't need to explicitly emit events,
// since all interested parties are bound to the same object and Angular
// takes care of updating sub-property bindings on changes.
if (!event.detail.path) {
this[this._eventNameForProperty(property)].emit(event.detail.value);
}
}
}
And then add an implementation for each element, along these lines:
@Directive({ selector: 'paper-tabs', host: { '(selected-changed)': '_emitChangeEvent("selected", $event)', '(selected-item-changed)': '_emitChangeEvent("selectedItem", $event)', '(items-changed)': '_emitChangeEvent("items", $event)', '(selected-values-changed)': '_emitChangeEvent("selectedValues", $event)', '(selected-items-changed)': '_emitChangeEvent("selectedItems", $event)' } }) export class PaperTabsChangeEventsAdapterDirective extends ChangeEventsAdapterDirective { @Output() selectedChange: any; @Output() selectedItemChange: any; @Output() itemsChange: any; @Output() selectedValuesChange: any; @Output() selectedItemsChange: any;
constructor() {
super(['selectedChange', 'selectedItemChange', 'itemsChange', 'selectedValuesChange', 'selectedItemsChange']);
}
}
I did this for all of the elements in my project, and they all seem to work, but it's definitely a hassle. I don't know of a cleaner way to manage it at this point though.
@dcoblentz Had a similar thought but didn't want to go down that route. Awesome work on your part. If this is the only way to achieve this for now, what do you think about creating a separate repo and sharing the definitions that you have and we could collaborate to bring all paperElements into it
I think AoT is essential with Angular 2. The 2+ sec parse time (which seems to be 10 sec on a tablet) just really not lives up to the promise of Angular 2. On the other hand, Material 2 will be soon there where Polymer elements are now (IMHO). So it is a good question if this is worth the effort. Do you guys think that it is of added value to maintain Polymer Angular 2 bridge in the long term? If so, what are your reasons?
@istvanszoboszlai
So yes, please continue this. At least until Material 2 will maybe become mature.
One thing to note about dcoblentz solution, it does enable two way data binding. But, it will require shadow dom fully enabled if you want to use components with content/slot. For example, using shady dom, something like:
<paper-input><span suffix>$</span></paper-input>
Won't work, because of the Polymer.dom dependency on web components with shady dom (As far as I saw, it won't be required on Polymer 2 as it uses dom functions directly). Angular2-Polymer solves this with the classes PolymerShadyDomAdapter: https://github.com/vaadin/angular2-polymer/blob/master/src/polymer-element.ts#L27
Or, have you find any solution that doesn't require that class or shadow dom fully enabled?
@rstpv I believe we could still continue to use a combination of both. The solution provided by @dcoblentz makes the directive declarations for each component static(which is required for AOT to work). We could still use the PolymerShadyDomAdapter provided by angular2-polymer as it is not directly linked to the creation of the directives but rather sets the Root DOM Adapter.
This is pretty rough, but here's a gist with the code I wrote, it's all pretty rough still, but I copied the output from my browser console to a new ts file, but it would of course be better to turn it into a cli tool that can generate each file directly.
https://gist.github.com/dcoblentz/b16e97bc5671a8c31ab65add8c88b041
We’re going to do a quick round of prototyping (2d timebox) to get a better understanding about this, what would be a viable fix for this issue.
Best news today so far :)
@dcoblentz, this is really awesome what you did. I do not get the whole process, however. How do you generate output.ts? Can this be applied to vaadin polymer elements, too?
We finished our research. Highlights below. Currently https://github.com/vaadin/angular2-polymer/issues/104 is prioritized as the next fix in the future, but after that AoT support will probably be the next one. ETA 2017Q1.
When following the Angular’s AoT guide (https://angular.io/docs/ts/latest/cookbook/aot-compiler.html) the development with angular2-polymer will fail when trying to compile the application.
You can reproduce the issue in angular2-polymer-quickstart AoT branch: https://github.com/vaadin/angular2-polymer-quickstart/tree/aot
Error: Error encountered resolving symbol values statically. Calling function 'PolymerElement', function calls are not supported.
Feature in Angular: https://github.com/angular/angular/blob/491d5a22a9dc1082e80aa5ca481aa02b49b9bfe8/modules/%40angular/compiler/src/aot/static_reflector.ts#L695 The reason for this limitation is that the AoT compiler needs to generate the code that calls the factory and there is no way to import a lambda from a module and you can only import an exported symbol. Meaning you can’t call functions in metadata. Code should be statically analyzable.
1) Extend useFactory: https://github.com/angular/angular/issues/10789#issuecomment-242220591 2) Generate Source Codes for each element: https://github.com/vaadin/angular2-polymer/issues/86#issuecomment-255398864 3) CLI-tool to generate source code for each element
if some one needs, I used polymer-element.ts to implement a class for directives generation, it is not a CLI-tool, but generates directives for a component, I hope helps you:
polymer-directive-generator.ts https://gist.github.com/axtlotic/06f8715a6ea0223af6fbd6cbf1266be7
app.component.ts https://gist.github.com/axtlotic/36764dc3747526aaa6254b39dc78a106
app.component.html https://gist.github.com/axtlotic/8ada0ade7244b412190a1d66e4c4abac
app.component.css https://gist.github.com/axtlotic/1113f933aee2a5e588161d6a8d0797e8
app.module.ts (example) https://gist.github.com/axtlotic/fddb1527f861c8fe8ad626d5bf3ff440
@axtlotic Could this be used to create a pre-built public package for all elements?
Any ideas when this will be fixed?
@mpartipilo thanks, if this is possible, I would have to install all the elements in my project and modify it to generate the directives, I hope to get the complete list of elements and give me some time to do it
@axtlotic Thanks for the generator. but when I use the generated code in my component. the ng build gave me this message:
chunk {0} main.bundle.js, main.bundle.map (main) 26.1 kB {2} [initial] [rendered] chunk {1} styles.bundle.js, styles.bundle.map (styles) 9.99 kB {3} [initial] [rendered] chunk {2} vendor.bundle.js, vendor.bundle.map (vendor) 2 MB [initial] [rendered] chunk {3} inline.bundle.js, inline.bundle.map (inline) 0 bytes [entry] [rendered]
ERROR in ./src/app/app.component.ts Module not found: Error: Can't resolve 'app.component.html' in '/Users/xukai/git/angular2/my-project/src/app' @ ./src/app/app.component.ts 21:22-51 @ ./src/app/index.ts @ ./src/main.ts @ multi main
ERROR in ./src/app/app.component.ts Module not found: Error: Can't resolve 'app.component.css' in '/Users/xukai/git/angular2/my-project/src/app' @ ./src/app/app.component.ts 22:21-49 @ ./src/app/index.ts @ ./src/main.ts @ multi main
what have I missed?
my module is like this:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { PolymerElement } from '@vaadin/angular2-polymer';
import { AppComponent } from './app.component';
import { PaperInput } from './paper-input-directives';
import { VaadinComboBox } from './vaadin-combo-box-directives';
@NgModule({
declarations: [
AppComponent,
PaperInput,
VaadinComboBox
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [],
entryComponents: [AppComponent],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }
and my component
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css'],
})
export class AppComponent {
title = 'app works!';
myLabel = 'Select a number';
myValue = '4';
myItems = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
}
and my template
<h1>{{title}}</h1>
<h2>{{title}}</h2>
<vaadin-combo-box [label]="myLabel" [(value)]="myValue" [items]="myItems"></vaadin-combo-box>
<paper-input [(value)]="myValue"></paper-input>
@axtlotic ok that was a path mistake I solved it by change templateUrl: 'app.component.html', styleUrls: ['app.component.css'], to templateUrl: './app.component.html', styleUrls: ['./app.component.css'],
thank you for your generator , it's good enough for me now.
How to use this generator? How to implement this solution?
@tomaszcysewski I created a generator project in Github here: https://github.com/hydraslay/ng2-polymer-static-gen And use the generated xxx.directives.ts file just like this project: https://github.com/hydraslay/ng2-polymer-static
There is still something need to be adjusted in vaadin-date-picker and vaadin-grid while other paper-xxx works well.
Those are most used elements I think. I want to install this in order to use vaadin-grid. Let's make a request for this adjusting, who develop this generator generally?
Unfortunately it is not working every time. If I am using a paper-dialog which has a vaadin-date-picker the dialog will not open. If I delete the containing vaadin-date-picker the dialog is working again. The vaadin-date-picker is working, but not with the dialog.
And I have some problems with paper-input in the paper-dialog. They do not show their actual value.
Do you may have some suggestions?
AOT is available (but first you should generated static directives). Check this repository
sounds like I have done twice AOT compile, One for Polymer, One for Angular...
@hydraslay thanks for sharing your solution. Yeah, looks like we can’t avoid some generation step for Polymer in general.
My idea on this — to try making a nicer generator using the polymer-analyzer
output, so that you don’t have to run the browser with elements and copy the generated directives code. This can be well automated, I believe. Prototyping this idea nowadays.
I would avoid publishing the generated directives, however, because then updating them for all the changes in all the elements is likely to turn into a big maintenance problem.
When using PolymerElement function inside the @NgModule, the AoT compiles complains with the following message:
Solutions to this error message have been provided in:
angular issue#10789
But almost all use the useFactory attribute as a workaround, but, declarations don't have such a feature.