1
- import { IAugmentedJQuery , IComponentOptions } from 'angular'
1
+ import {
2
+ IAugmentedJQuery ,
3
+ ICompileService ,
4
+ IComponentOptions ,
5
+ IScope ,
6
+ ITranscludeFunction
7
+ } from 'angular'
2
8
import fromPairs = require( 'lodash.frompairs' )
9
+ import HTMLtoJSX = require( 'htmltojsx' )
10
+ import Parser = require( 'html-react-parser' )
3
11
import NgComponent from 'ngcomponent'
4
12
import * as React from 'react'
5
13
import { render , unmountComponentAtNode } from 'react-dom'
6
14
15
+ const converter = new HTMLtoJSX ( {
16
+ createClass : false
17
+ } )
18
+
7
19
/**
8
20
* Wraps a React component in Angular. Returns a new Angular component.
9
21
*
@@ -25,17 +37,47 @@ export function react2angular<Props>(
25
37
26
38
return {
27
39
bindings : fromPairs ( names . map ( _ => [ _ , '<' ] ) ) ,
28
- controller : [ '$element' , class extends NgComponent < Props , void > {
29
- constructor ( private $element : IAugmentedJQuery ) {
40
+ controller : [ '$element' , '$transclude' , '$compile' , class extends NgComponent < Props , void > {
41
+ private transcludedContent : JQuery
42
+ private transclusionScope : IScope
43
+
44
+ constructor ( private $element : IAugmentedJQuery , private $transclude : ITranscludeFunction , private $compile : ICompileService ) {
30
45
super ( )
31
46
}
47
+
32
48
render ( ) {
49
+ let children
50
+ this . $transclude ( ( clone : JQuery , scope : IScope ) => {
51
+ children = Array . prototype . slice . call ( clone ) . map ( ( element : HTMLElement ) => {
52
+ this . $compile ( element ) ( scope )
53
+ const phase = scope . $root . $$phase
54
+ if ( phase !== '$apply' && phase !== '$digest' ) {
55
+ scope . $apply ( )
56
+ }
57
+ return converter . convert ( element . outerHTML )
58
+ } )
59
+ this . transcludedContent = clone
60
+ this . transclusionScope = scope
61
+ } )
33
62
// TODO: rm any when https://github.com/Microsoft/TypeScript/pull/13288 is merged
34
- render ( < Class { ...( this . props as any ) } /> , this . $element [ 0 ] )
63
+ render (
64
+ < Class { ...( this . props as any ) } >
65
+ { Parser ( children && ( children as string [ ] ) . join ( '' ) ) }
66
+ </ Class > ,
67
+ this . $element [ 0 ]
68
+ )
35
69
}
70
+
36
71
componentWillUnmount ( ) {
37
72
unmountComponentAtNode ( this . $element [ 0 ] )
38
73
}
39
- } ]
74
+
75
+ $onDestroy ( ) {
76
+ super . $onDestroy ( )
77
+ this . transcludedContent . remove ( )
78
+ this . transclusionScope . $destroy ( )
79
+ }
80
+ } ] ,
81
+ transclude : true
40
82
}
41
83
}
0 commit comments