在react项目中集成angularJS

版权声明:本文为博主原创文章,欢迎转载,转载请注明出处。 https://blog.csdn.net/smk108/article/details/80931303

注:Demo源码地址:https://github.com/smk108/react-angular

ReactAngular都是主流的前端框架,我参与的前端项目通常都是使用react开发,因为要在自己开发的项目中使用一个由angular开发的开源项目,因此开始尝试两大主流框架的集成。

React文档中讲到了react可以第三方库整合,是以jQuery Backbone为例讲解了将其他应用添加到react 项目里。本文以一个测试demo为例介绍一下如何将angularJS集成到react 项目里。

首先,是在reactrender方法中声明一个div容器,这个div容器可以简单设置一些静态的属性,但是不能设置会触发react更新这个容器的属性或子元素,这样保证react不会更新这个div容器。

render() {
  return (
    <div className="main">
      <Timer
        time={this.state.time}
        firstName={this.state.firstName}
        lastName={this.state.lastName}
        handleNameChange={this.handleNameChange}/>
      <div ng-app="app" ng-controller="myCtrl" ref={ref => this.angularDiv = ref}>
        <angular-div></angular-div>
      </div>
    </div>
  );
}

然后,编写html模板,例如:

<div>angular中显示名: <input type="text" ng-model="firstName"></div>
<div>angular中显示姓: <input type="text" ng-model="lastName"></div>
</div>angular中显示姓名: {{firstName + "." + lastName}}</div>

最后,在angular控制器中声明自定义指令angularDiv:

let appComponent = {
  restrict: 'E',
  template: require('./test.html'),
};
angular.module('app', [])
  .directive('angularDiv',function(){
    return appComponent
  })
  .controller('myCtrl',['$scope',function($scope){
    $scope.firstName= "John";
    $scope.lastName= "Doe";
    $scope.update = function (attr, value) {
      $scope[attr] = value;
      $scope.$apply();
    }
  }]);

我在控制器中定义了update方法,用以在外部更新$scope中的值。

在外部获取$scope的方法为:

angular.element(this.angularDiv).scope()

更新$scope值的方式为:

angular.element(this.angularDiv).scope().update('firstName', test)

这样,就简单实现了将angular项目集成到react项目中的需求。最终demo显示效果如下:

当修改react组件中的input框内容时,angularJs中显示的内容会与之同步更新,当然,angularJsinput框可以自己修改。该demo的功能非常简单,在开发中应该根据实际需求进行开发扩展。

在集成过程中还有几个问题需要注意:

  1. 可以不在$scope中定义update方法,在外部获取到$scope后直接赋值,但是必须要调用$scope.$apply()才能生效;
  2. 控制器的定义不管是放在生命周期componentDidMount中,还是在单独js文件中定义然后通过import导入,控制器的定义都比react生命周期componentDidMount的执行有延迟。因此,如果再页面渲染完成立即使用代码获取$scope会得到undefined,提供参考的解决方法有:
  • setTimeout()设置一定延时;
  • 在控制器的定义代码末尾抛出一个事件,在react中监听该事件,监听到事件后再通过代码获取$scope,然后实现需要的功能;
  • 循环查询控制器的定义是否完成或获取到的$scope是否已经定义,满足一定条件后再进行相关操作

这是我在测试框架集成过程中遇到的问题,如果有更友好的方式解决这个问题,还请不吝指教。

猜你喜欢

转载自blog.csdn.net/smk108/article/details/80931303