diff --git a/index.tsx b/index.tsx index f4067d9..e12d67a 100644 --- a/index.tsx +++ b/index.tsx @@ -1,7 +1,7 @@ import * as angular from 'angular' import kebabCase = require('lodash.kebabcase') -import { $injector as defaultInjector } from 'ngimport' import * as React from 'react' +import { $injector as defaultInjector } from 'ngimport' interface Scope extends angular.IScope { props: Props @@ -39,16 +39,15 @@ export function angular2react( $injector = defaultInjector ): React.ComponentClass { - return class extends React.Component> { + return class Component extends React.Component> { state: State = { - didInitialCompile: false + didInitialCompile: false, + scope: Object.assign(this.getInjector().get('$rootScope').$new(true), { props: writable(this.props) }), } - componentWillMount() { - this.setState({ - scope: Object.assign($injector.get('$rootScope').$new(true), { props: writable(this.props) }) - }) + getInjector() { + return $injector || angular.element(document.querySelectorAll('[ng-app]')[0]).injector(); } componentWillUnmount() { @@ -64,10 +63,15 @@ export function angular2react( // called only once to set up DOM, after componentWillMount render() { - const bindings: {[key: string]: string} = {} + const bindings: { [key: string]: string } = {} if (component.bindings) { for (const binding in component.bindings) { - bindings[kebabCase(binding)] = `props.${binding}` + if (component.bindings[binding].includes('@')) { + // @ts-ignore + bindings[kebabCase(binding)] = this.props[binding]; + } else { + bindings[kebabCase(binding)] = `props.${binding}`; + } } } return React.createElement(kebabCase(componentName), @@ -77,12 +81,14 @@ export function angular2react( // makes angular aware of changed props // if we're not inside a digest cycle, kicks off a digest cycle before setting. - componentWillReceiveProps(props: Props) { - if (!this.state.scope) { - return + static getDerivedStateFromProps(props: Props, state: State) { + if (!state.scope) { + return null } - this.state.scope.props = writable(props) - this.digest() + state.scope.props = writable(props) + Component.digest(state.scope) + + return {...state}; } private compile(element: HTMLElement) { @@ -90,16 +96,17 @@ export function angular2react( return } + const $injector = this.getInjector(); $injector.get('$compile')(element)(this.state.scope) - this.digest() + Component.digest(this.state.scope) this.setState({ didInitialCompile: true }) } - private digest() { - if (!this.state.scope) { + static digest(scope: Scope) { + if (!scope) { return } - try { this.state.scope.$digest() } catch (e) { } + try {scope.$digest() } catch (e) { } } } diff --git a/package.json b/package.json index 85aae95..450d3af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "angular2react", - "version": "3.0.2", + "version": "6.0.0", "description": "One line of code to turn any Angular 1 Component into a React Component", "main": "index.js", "main:esnext": "index.es2015.js", @@ -69,10 +69,10 @@ }, "peerDependencies": { "@types/angular": ">=1.5.0", - "@types/react": ">=15.0.0", - "@types/react-dom": ">=15.0.0", + "@types/react": ">=17.0.0", + "@types/react-dom": ">=17.0.0", "angular": ">=1.5.0", - "react": ">=15.0.0", - "react-dom": ">=15.0.0" + "react": ">=17.0.0", + "react-dom": ">=17.0.0" } }