Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSX like templates in angular #5131

Closed
malekpour opened this issue Nov 4, 2015 · 65 comments
Closed

JSX like templates in angular #5131

malekpour opened this issue Nov 4, 2015 · 65 comments

Comments

@malekpour
Copy link

It would be cool to support JSX like templates in angular 2. JSX can hold all required information required to generate the DOM at run time. Following are some benefits come with JSX to angular:

  1. Type safety to catch errors at compile time
  2. Better run time performance. No need to parse template string at run time. DOM info and may be AST can be serialized at compile time
  3. Typescript already supports JSX and understands the syntax
  4. More intelligence and easier refactoring support for IDEs when dealing with templates
  5. Possibility to share component templates with React
@bradlygreen
Copy link
Contributor

Agree that this might be nice for folks who like JSX, but it will have to be an external contributor who works on it rather than the core team as most of this is opinion rather than benefits. My thoughts:

1 & 4: can work fine with Angular 2 templates. Already demonstrated start of this in WebStorm. Coming in other IDEs soon.

2: Angular likely performs better than JSX as compilation happens as a build step (landing soon).

5: Yes, this could be nice and could work well for folks using Flux style data flow. There will likely soon be more components in native Angular 2, however, so not so sure of the actual benefit to the ecosystem.

In general, we like the HTML-spec compliant template as all tools work with them and designers have easier time interacting with them.

@thelgevold
Copy link
Contributor

@bradlygreen @malekpour
I would argue that you can do this, to some degree today, using TypeScript to seamlessly bridge the two technologies. In the end it's just JavaScript...

I have an example here where I integrate a Flux/React based component into an Angular 2.0 component:
http://www.syntaxsuccess.com/angular-2-samples/#/demo/react

Some more details here too:
http://www.syntaxsuccess.com/viewarticle/integrating-react-with-angular-2.0

@malekpour
Copy link
Author

@bradlygreen I agree on almost all of your points. I didn't mean to change anything in the current Angular 2 design or removing the run time template parsing which I am a big fan of. To clarify what I mean please compare these two components:

@Component({
  selector: 'key-up',
  template: `
    <div>    
      <h4>Give me some keys!</h4>
      <div><input (keyup)="onKey($event)"><div>
      <div>{{values}}</div>
    </div>
  `
})
class TestComponent {
  values = '';
  onKey(event) {
  }
}
@Component({
  selector: 'key-up',
  templateJsx: (
    <div>
      <h4>Give me some keys!</h4>
      <div><input (keyup)={ onKey($event) }><div>
      <div>{{values}}</div>
    </div>
  )
})
class TestComponent {
  values = '';
  onKey(event) {
  }
}

While onKey in the first template is double quoted string inside another multi line string, in the JSX template it is an identifier and it makes more sense.

Also compiler would generate something similar to this which I strongly doubt if any parser can perform better than this at run time. create will have 3 parameters, tag/directive name, attributes and children.

AngularJsx.create("div", null, 
  AngularJsx.create("h4", null, "Give me some keys!"), 
  AngularJsx.create("div", null, AngularJsx.create("input", {keyup:  onKey($event) })), 
  AngularJsx.create("div", null, {values})
)

I am not aware of the plan you mentioned in your comment (number 2), but even better if angular will support compiled templates. So the JSX compiler will output the same.

And don't forget that this will be a great attraction for react community members to contribute or migrate.

@malekpour
Copy link
Author

And this is funny, I randomly copied the above component snippet from https://angular.io/docs/ts/latest/guide/user-input.html page. Only when I tried to compile the JSX template, I realized that the div element in the line <div><input (keyup)="onKey($event)"><div> is not closed.
https://github.com/angular/angular.io/blob/master/public/docs/_examples/user-input/ts/src/app/app.ts#L36
This mistake is repeated in that page at least 4 times by the documentation team. These kind of mistakes are very common and type safe template support helps a lot.

@robwormald
Copy link
Contributor

@malekpour you may want to have a look at the design documentation for the template compiler - it outputs code not unlike JSX : https://docs.google.com/document/d/11r8IuS4xDyhVSEBp7fDYo7aiLYsLEXKs4lPd36umUGM/edit

That said, you could certainly implement this as a 3rd party render plugin - in fact, we have a react-native renderer that might get you started: https://github.com/angular/react-native-renderer/

@thelgevold super cool demos by the way - your components page is great!

@thelgevold
Copy link
Contributor

Thanks @robwormald I appreciate that!

@mohsen1
Copy link

mohsen1 commented Nov 6, 2015

I never liked the idea of XML in my JavaScript. The only benefit I can see is static analysis of template HTML strings. It's possible to write static analyzers that lint those HTML strings though. You can either mark the template strings with a tag function like

html`<div>...</div>`

or somehow use TypeScript type system to hint a string is HTML...

@RainingNight
Copy link

I like templateJsx.

@PavelPZ
Copy link

PavelPZ commented Feb 16, 2016

+1 templateJsx
@mohsen1 "I never liked the idea of XML in my JavaScript":

  • Don’t put XML to JavaScript, keep it in separate file. However, have it TYPED including all Atom or Visual Studio IDE benefits: find all symbol reference, rename symbol, syntax highlighting, auto indent, etc.
  • When CSS designer accidentally corrupts your JavaScript fragment in HTML template, Typescript compiler will notify you.
  • etc.

@PavelPZ
Copy link

PavelPZ commented Feb 17, 2016

This issue is solving in Typescript project, see @MikeRyan52 comment in #7100.

@remojansen
Copy link

When using TypeScript the templates are strongly typed (TSX) this helps to prevent errors and to provide a better development experience I 👍 for TSX template support!

@robwormald
Copy link
Contributor


😃

@mohsen1
Copy link

mohsen1 commented Feb 22, 2016

Unlike politicians I'm not afraid to say I've changed my mind about JSX!

Using TypeScript and JSX (TSX) has been a pleasure in my recent react project. Typed HTML is really great!

@robwormald
Copy link
Contributor

See below for typed HTML that's actually HTML, coming soon to an Angular near you

@doczoidberg
Copy link

this is great. Will this also be possible in linked html templates via templateurl?

I don't understand the closing of the other issue. This is more a typing thing than a jsx one?

@RainingNight
Copy link

@robwormald It's great than jsx.

@malekpour
Copy link
Author

TSX and in general JSX benefits are not limited to editor intellisense and syntax coloring.

I personally like the way JSX naturally eliminates run-time parse and AST generation, comparing to current Angular 2 template parsing or even future build time template compilation.

Please do not forget that jsx !== React, it is just invented by React team. I think Angular team can support this as an incentive for React community to migrate. Here is proposed JSX specification https://facebook.github.io/jsx/

@mohsen1
Copy link

mohsen1 commented Feb 23, 2016

I like where TypeScript extensibility is going to and I can see some day typescript drops all of JSX stuff and move it to an extension. What I saw on the issue referenced above is better than JSX actually. JSX has its own pitfalls like class keyword conflict and so on. I'm sure what typescript team is working on is going to be better and we shouldn't really ask Angular team to support JSX.

@malekpour
Copy link
Author

@mohsen1 I agree that TypeScript Extensibility is so cool, but why

we shouldn't really ask Angular team to support JSX

@mohsen1
Copy link

mohsen1 commented Feb 23, 2016

@malekpour because it can be solved in programming language level?

@malekpour
Copy link
Author

@mohsen1 You are right that it can be solved in programming language level. In fact it is already solved by TSX and supported by TypeScript for a while now.

Regardless of how TypeScript Extensibility can help in development time, value type of template will remain string which needs to be parsed and analysed at run-time, but value of templateJsx will be ready to use object or function.

@MikeRyanDev
Copy link
Member

value type of template will remain string which needs to be parsed and analysed at run-time

This is not true. There is already a PR open that will compile templates as part of the build step instead of at runtime #7155

@malekpour
Copy link
Author

This is not true. There is already a PR...

@MikeRyan52 So, simply that is true unless you post-compile templates in an additional build step.

@mohsen1
Copy link

mohsen1 commented Feb 23, 2016

I don't exactly know how TypeScript extensibility will work out with Angular but I hope it's going to be better than TSX. Two issues I have in TSX that I think the new proposal will fix:

  • No more className instead of class
  • Allowing <Type> syntax within the template. Currently in TSX it's impossible to do something like return (<div>{(<Foo>bar).baz}</div>)

@malekpour
Copy link
Author

In TSX you can use (bar as Foo).baz instead of (<Foo>bar).baz.

This 10 line jsbin shows how easily a TSX template works
http://jsbin.com/yodiwid/edit?js,output

@mohsen1
Copy link

mohsen1 commented Feb 23, 2016

Yes, I'm aware of that. Thank you for the gist though!

@PavelPZ
Copy link

PavelPZ commented Feb 29, 2016

Maybe I missed something - in this case sorry for the following…

From my point of view, angular runtime have to analyze both template-string and templateUrl-file in order to composite Component tree. "Analyze" means to convert string to any JavaScript representation (object tree or something similar).

TSX (parsed into JavaScript object tree by TypeScript, in compile time) could be another representation of Angular template. Maybe I am wrong but solving microsoft/TypeScript#6508 issue must be much more difficult than using JavaScript object tree as another Angular template representation. Besides,
microsoft/TypeScript#6508 is not an ideal solution, it solves only some of the issues (refactoring, intellisense etc.). I does not solve another huge benefit of JSX/TSX approach: its functional nature:

  • “Template as function” opens other templating possibilities
  • it is not bound to Typescript

I think that “Template as function” is a bit different from "JSX like templates in angular" so I created new #7339 issue.

Angular 2 orientation on Typescript (together with "Angular - one framework" concept) was one of the main reasons I left React to Angular. The only thing I am missing now are strictly typed functional templates.

Thanks @malekpour for many excellent arguments supporting TSX/JSX/functional templates idea. I believe Angular team will listen to them.

@Inlesco
Copy link

Inlesco commented May 24, 2017

Another React and JSX lover chiming in: everything about NG2 is fine until there's the "good old" HTML templates coming in with the custom attributes for onClick, onBlur and other ev. handlers, basic map functions, etc.

I'd like to ask - WHY? Why NG2 templates must contain some obscure HTML-like attributes that accepts a string to run a loop? Why the the ev. handlers must have some kind of prefix? Why it must NOT be consistent to the usual HTML that front-end devs work with?

Look at JSX. It's very simple. It has very clean, approachable and well-defined syntax. Scopes are very clearly defined by the correct usage of curly braces. It's plain JS. It doesn't try to reinvent the wheel like NG2 templates.

And speaking of the ease for designers to modify the rendered content (HTML vs JSX), from my experience, if a designer is capable, it's very easy for him to explain how JSX works instead of all the weird *ngIf, etc. HTML attrs.

For me, personally, JSX is the clear winner here. Of course, that's debatable and it's a matter of habit in general, but at least both sides are allowed to speak out and compare things :)

@gioragutt
Copy link

@Inlesco just have to note, that I find it unlikely that a designer will have a better time modifying an JSX template with JS involved in it, rather than an HTML that has *ngFor in it.

@zontafil
Copy link

@gioragutt a designer finds it difficult to modify xml templates for android apps. That's not a valid reason to use html for building android apps

@gioragutt
Copy link

@m3l7 consider this:

Hey matt, can you please help me align the textbox in trade-form.component.html?

versus

Hey matt, can you please help me align the textbox in TradeFormComponent.tsx? Yeah, just look for the render function, and don't forget that you have to use className instead of class

And so on. Of course this is opinionated, I'm not saying one approach is absolutely better than the other. Unlike what I always hear from React developers: Ha we do data.map(...) so it's so much better than *ngFor. This means nothing. You're gonna get shit done either way. Only reason today to choose React over Angular or the other way around - is people's opinions. If you/your ceo/your cto/whatever love React more than you do Angular, you're gonna do React. Same for vice versa.

This also implies for all other frameworks/libraries out there. All this Vue/Aurelia or the other dozens of frameworks. Who needs that shit. The community should pick a couple of good ones (aka React / Angular) and improve the living hell out of them. Publishing all those dozens of libraries ain't gonna get any progress.

@zontafil
Copy link

@gioragutt it's not an opinion. Type checking in templates is a huge step forward.

For the second point: correct, that's why many people take angular and try to improve it (i.e. by adding jsx/tsx)

@egaga
Copy link

egaga commented Jul 28, 2017

@m3l7 Yes, type checking is important, and is possible in Angular templates with typescript language service. On the other hand, having unlimited expressiveness in templates hinders tooling support and has other implications, such as how much energy one potentially needs to spend understanding a template file. On that one can have opinion whether it is worth the power and consistency of having same language.

@gioragutt
Copy link

gioragutt commented Jul 28, 2017

@m3l7 As @egaga said, You can have Type checking and linting and validation in general in html templates. In fact, this comes built in with angular today. I think that it's might worth mentioning that comparing *ngFor to items.map(item => ...) might not be that worth doing, likewise for *ngIf, since there are stuff behind it that aren't just foring over a collection, like map.

Also, take for example: pipes. How easy it is to use pipes, how expressive it is and how well it integrates into templates. As someone who works with linux and bash daily, the concept of pipes is so clear and intuitive, let alone composable. It takes a bit more in pure JS to do that.

@robwormald
Copy link
Contributor

See - https://github.com/angular/vscode-ng-language-service

Our position on this has not changed, nor is it likely to. You are, of course, welcome to integrate React or any of the JSX-based libraries into Angular, as it's trivial to do yourself. We will not be supporting this in Angular core.

@windmaomao
Copy link

Then u just open the market for Vue

@Jonatthu
Copy link

Jonatthu commented Jun 13, 2018

@robwormald We need a way to have strong type html integrated with typescript, finding references and refactoring features based on this references. The same for selectors of components, We should not use a selector name string based, instead use the class name of the component, so we can find references based on the class instead the selector and do quick refactoring instead finding and replacing. C'mon guys angular can do it better on this, please take a decision soon before it is too late.

@Jonatthu
Copy link

@bradlygreen Please make it happen a lot of benefits will be for angular if this happens

@John0x
Copy link

John0x commented Nov 21, 2018

Are there any third party libs that can accomplish this as of right now?

@basarat
Copy link
Contributor

basarat commented Nov 23, 2018

@John0x It would be counter productive to use angular without its native features / choices 🌹

@arnotes
Copy link

arnotes commented Jan 17, 2019

please make this happen :)

@KamiShikkaku
Copy link

The fact that people are actually using the className argument to dismiss the benefits of JSX is laughable. In my opinion, this issue is Angular's largest failing as a front-end framework in terms of the developer experience, and this complacence is only going to lose Angular more and more ground to the other major frameworks.

@mlc-mlapis
Copy link
Contributor

mlc-mlapis commented Feb 2, 2019

@KamiShikkaku ... if you like JSX so much, you may be interested in the NG-VDOM, introduced by @trotyl ... see:
https://blog.angularindepth.com/introducing-to-ng-vdom-a-new-way-to-write-angular-application-60a3be805e59

@icenold
Copy link

icenold commented Mar 8, 2019

lets not forget about this
#21224

@Inlesco
Copy link

Inlesco commented Mar 8, 2019

I don't really get why Angular devs are against the variety of templating languages available on the market. The more we have, the better, especially if it's something thought-out, powerful and TS-compatible like JSX.

If JSX happens and, presumably, hits the deck big time, some will continue to use NgJs' HTML templating, some will jump ship and migrate their apps to JSX. Where's the problem here? Definitely nowhere, the way I see it.

@mlc-mlapis
Copy link
Contributor

@Inlesco ... not sure that it's true.

The more we have, the better ...

@windmaomao
Copy link

@Inlesco probably JSX is the signature of React whereas Html is one of the signatures of Angular.

@mitevdev
Copy link

mitevdev commented Apr 1, 2019

I have a component with dynamic dropdown menu which I want to configure from within the child components (context menu). This is 5 mins work with React, what about Angular?

@mlc-mlapis
Copy link
Contributor

@mitevdev ... a component with dynamic dropdown usually has an input with its configuration. Not sure what a child component (context menu) is and why it's a child of the dropdown component at all.

@mitevdev
Copy link

mitevdev commented Apr 2, 2019

There is a component A (parent) which is a wrapper for component B (child). A has a toolbar wich can be customized by component B. There are many different implementations of B but A stays always the same. The contents of that toolbar may vary with the implementation of B.

Of course, I can "predict" all possible combinations and use *ngIf or *ngSwitch but this is not so elegant as if component B could just sent the contents (elements) configured as views and callback handlers as well (which is exactly what React supports).

@khaledosman
Copy link

@mitevdev I think <ng-content> / slots should work for your case, it acts like props.children in React

@mitevdev
Copy link

mitevdev commented Apr 2, 2019

@khaledosman good point, looking for <ng-content> I've found <ng-container> in relation to *ngTemplateOutlet which seems to be solution for my case.

The idea behind is to define the toolbar's elements within child component B:

...
<ng-template #element1>...</ng-template>
...

Component A fetches the IDs of that elements and use <ng-container *ngTeplateOutlet=""> to render the elements defined in B.

<ng-container *ngTemplateOutlet="element1"></ng-container>

The only I need to test is if the elements IDs are available on global scope without the need to disable the default component encapsulation.

UPDATE: It works ....!

@KamiShikkaku
Copy link

Not that I'm against people asking for help, but @mitevdev's problem is barely even tangentially related to the issue of support for JSX in Angular. Would be nice to stay on topic.

@JamesMcGuigan
Copy link

@John0x "Are there any third party libs that can accomplish this as of right now?"

My google-fu has turned up this currently experimental library: ng-vdom.

I've not yet tested it, but it claims to provide support for React style render() methods with JSX inside Angular

https://blog.angularindepth.com/introducing-to-ng-vdom-a-new-way-to-write-angular-application-60a3be805e59

https://github.com/trotyl/ng-vdom

@avin-kavish
Copy link

avin-kavish commented May 17, 2019

The best solution to this problem is to use React.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests