AngularJS React App 中的指令
AngularJS Directive into React App
我们正在考虑使用 React 编写一个新的应用程序,但需要一些特定于我们业务的现有 Angular 指令,例如修改后的 Angular 日期选择器。组件太多,我们无法全部重写。
不知道有没有人有经验或者知道这样做的努力和可行性?
到目前为止,我设法找到的唯一一篇关于此的文章是。我发现的大多数资源都提到了从添加了 React 的 Angular 应用程序的另一种方式。 http://softeng.oicr.on.ca/chang_wang/2017/04/17/Using-AngularJS-components-directives-in-React/
有一个名为 angular2react 的库可以在 React 组件中重用 angularjs 代码。你可以看看它是否符合你的需要。 :)
我写了一个简单的演示应用程序来展示如何实现它:react-angularjs-bridge
基本步骤如下:
- 创建一个反应组件,它将在 DOM 中托管 angular 组件。此组件应始终呈现一个简单的 html 元素(例如
HTMLDivElement
),以便在协调虚拟 DOM 与真实 DOM 时反应不会混淆。
- 挂载 React 组件后
componentDidMount
,在渲染的 HTMLDivElement
下创建影子根并初始化其下的 angular 应用程序。这将确保 angularJS 组件被封装并且不受反应应用程序的影响,反之亦然
单击 here 观看演示。检查 React 应用程序样式如何不影响 angular 组件的样式。
独立于Angular,ref
是一种方法:它提供了对底层DOM节点的访问以及操纵DOMinside 该节点以任何你喜欢的方式,包括 AngularJS。您的更改将保留 - 至少直到反应完全清除组件。
您可以通过
在 React 中创建一个引用
<divOrAnyOtherDom ref={((el) => {this._elem=el;}).bind(this)}></...
(有关完整说明和达到相同目的的替代方法,请参见此处:https://reactjs.org/docs/refs-and-the-dom.html#callback-refs)
无论如何,由于您现在有一个 DOM 节点,您可以开始使用它,即将 angular 添加到 componentDidMount
内的混音中。可悲的是,这并不是很明显 - 这是过去对我有用的一种方法(moduleName
需要是一个你已经按照你的逻辑放置的模块):
let baseElement = angular.element(this._elem);
let templateElement = angular.element(templateSource);
angular.injector([ 'ng', moduleName ]).invoke(function($compile, $rootScope) {
let cmp = $compile(templateElement);
scpe = $rootScope.$new(false);
scpe.varname = whateverYouHave; # point is: you can set scope variables
cmp(scpe);
baseElement.append(templateElement);
scpe.$digest();
});
现在 angular 在 DOM 节点 react 给了你。
(我从一个稍微不同的集成中得到了这个:Vaadin 到 AngularJS,但原理是一样的:Vaadin,就像 react 一样,给你一个 DOM 节点。当您对完整代码感兴趣:https://github.com/akquinet/vaangular/blob/master/vaangular/src/main/resources/de/akquinet/engineering/vaadin/vaangular/angular/NgTemplate.js)
另外:对于来自 angular 组件的任何回调,您可能必须使用 setState
等
我们正在考虑使用 React 编写一个新的应用程序,但需要一些特定于我们业务的现有 Angular 指令,例如修改后的 Angular 日期选择器。组件太多,我们无法全部重写。
不知道有没有人有经验或者知道这样做的努力和可行性?
到目前为止,我设法找到的唯一一篇关于此的文章是。我发现的大多数资源都提到了从添加了 React 的 Angular 应用程序的另一种方式。 http://softeng.oicr.on.ca/chang_wang/2017/04/17/Using-AngularJS-components-directives-in-React/
有一个名为 angular2react 的库可以在 React 组件中重用 angularjs 代码。你可以看看它是否符合你的需要。 :)
我写了一个简单的演示应用程序来展示如何实现它:react-angularjs-bridge
基本步骤如下:
- 创建一个反应组件,它将在 DOM 中托管 angular 组件。此组件应始终呈现一个简单的 html 元素(例如
HTMLDivElement
),以便在协调虚拟 DOM 与真实 DOM 时反应不会混淆。 - 挂载 React 组件后
componentDidMount
,在渲染的HTMLDivElement
下创建影子根并初始化其下的 angular 应用程序。这将确保 angularJS 组件被封装并且不受反应应用程序的影响,反之亦然
单击 here 观看演示。检查 React 应用程序样式如何不影响 angular 组件的样式。
独立于Angular,ref
是一种方法:它提供了对底层DOM节点的访问以及操纵DOMinside 该节点以任何你喜欢的方式,包括 AngularJS。您的更改将保留 - 至少直到反应完全清除组件。
您可以通过
在 React 中创建一个引用<divOrAnyOtherDom ref={((el) => {this._elem=el;}).bind(this)}></...
(有关完整说明和达到相同目的的替代方法,请参见此处:https://reactjs.org/docs/refs-and-the-dom.html#callback-refs)
无论如何,由于您现在有一个 DOM 节点,您可以开始使用它,即将 angular 添加到 componentDidMount
内的混音中。可悲的是,这并不是很明显 - 这是过去对我有用的一种方法(moduleName
需要是一个你已经按照你的逻辑放置的模块):
let baseElement = angular.element(this._elem);
let templateElement = angular.element(templateSource);
angular.injector([ 'ng', moduleName ]).invoke(function($compile, $rootScope) {
let cmp = $compile(templateElement);
scpe = $rootScope.$new(false);
scpe.varname = whateverYouHave; # point is: you can set scope variables
cmp(scpe);
baseElement.append(templateElement);
scpe.$digest();
});
现在 angular 在 DOM 节点 react 给了你。
(我从一个稍微不同的集成中得到了这个:Vaadin 到 AngularJS,但原理是一样的:Vaadin,就像 react 一样,给你一个 DOM 节点。当您对完整代码感兴趣:https://github.com/akquinet/vaangular/blob/master/vaangular/src/main/resources/de/akquinet/engineering/vaadin/vaangular/angular/NgTemplate.js)
另外:对于来自 angular 组件的任何回调,您可能必须使用 setState
等