当前位置:  开发笔记 > 编程语言 > 正文

将Angular应用程序与ReactJS应用程序连接?

如何解决《将Angular应用程序与ReactJS应用程序连接?》经验,为你挑选了1个好方法。

我有一个Angular应用程序,我想在ReactJS中编写应用程序的某些部分。

如何将ReactJS应用程序注入现有的Angular应用程序中?我还需要组件的双向通信。



1> kris_IV..:

您可能需要其他选项,所以我在第2段中写了它:

无需通信的Angular-ReactJS

具有双向通信的Angular-ReactJS

下面的所有代码都是最少的,只能在出现的步骤上显示问题。在GitHub上,您拥有完整的代码来解决问题,以下示例并不总是1:1,因为此代码已扩展。

无需通信的Angular-ReactJS

要将ReactJS应用添加到现有的Angular应用中,您需要安装5个npm依赖项:reactreact-dom

npm install --save react
npm install --save react-dom
npm install --save-dev @types/react
npm install --save-dev @types/react-dom
npm install --save-dev @types/react-select

下一步-我们应该允许jsx.tsx文件中使用模板,因此我们应该进行编辑tsconfig.json并添加:

{
    ...
   "compilerOptions": {
    …
    "jsx": "react"
}

如果使用WebStorm,则应重新启动项目,因为tslint会显示错误,直到重新启动。

为了保持结构清晰,我创建了以下目录结构:

angular /
  ng-hero.component.ts // Component in Angular
  react-renderer.component.ts // ReactJS renderer without communication
react /
  react-application.tsx // React init application
  react-hero.tsx // React hero component
app.component.html
app.component.ts

现在,您需要在Angular中创建特殊组件,该组件将负责嵌入ReactJS应用程序。我将调用此组件ReactRendererComponent。这个组件非常简单,它只有一行模板行,带有的构造函数import Injector和一行ngOnInit

@Component({
  selector: 'app-react-renderer',
  template: `
` }) export class ReactRendererComponent implements OnInit { constructor(public injector: Injector) { } ngOnInit() { ReactApplication.initialize('react-renderer', this.injector); } }

现在我们需要ReactApplication在其中初始化ReactJS应用程序的组件:

interface IReactApplication {
  injector: Injector;
}

class ReactApp extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      

ReactJS component:


); } } export class ReactApplication { static initialize( containerId: string, injector: Injector ) { ReactDOM.render( , document.getElementById(containerId) ); } }

我们需要ReactHero以下示例中使用的组件:

class ReactHero extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    return (
      
        react-hero works!
Don't have any data
); } } export default ReactHero;

在Angular App中,我们应该使用ReactRenderercomponent,所以我们使用:

App.component data:

This is Angular

Angular Logo

目前,我们有带有嵌入式ReactJS应用程序的Angular应用程序,但没有任何通信。对您来说足够了吗?如果是的话,就这些了。如果您需要在两个应用程序之间进行任何形式的通信,请在下面为您介绍RxJS选项。

具有双向通信的Angular-ReactJS

在此示例中,RxJS支持双向数据绑定。您可以获取此数据,并在ReactJS应用和Angular应用中使用它们以查看所有更改。对于许多项目来说,这已经足够了,但是您可以使用其他选项来获得这种双向通信,例如,可以对它们使用Redux。

为了清楚起见,下面我将提供此部分的完整目录结构:

angular /
  hero.service.ts
  ng-hero.component.ts // Component in Angular
  react-bidirectional-renderer.component.ts // ReactJS renderer with bidirectional communication
model /
  hero.ts // interface for Hero object
react-bidirectional
  react-bidirectional-application.tsx // React init application with bidirectional communication
  react-bidirectional-hero.tsx // React hero component with RxJS support
app.component.html
app.component.ts

首先,我们创建IHero带有数据的接口:/model/hero.ts

export interface IHero {
  name: string;
  age: number;
}

在下一步中,我们创建angular/hero.service.ts服务,以在应用程序的Angular部分中使用它:

@Injectable({
  providedIn: 'root'
})
export class HeroService {
  private heroes$: BehaviorSubject = new BehaviorSubject([]);

  constructor() {
  }

  addHeroes(hero: IHero) { // To add new hero
    const actualHero = this.heroes$.value;
    actualHero.push(hero);
    this.heroes$.next(actualHero);
  }

  updateHeroAge(heroId: number, age: number) { // To update age of selected hero
    const actualHero = this.heroes$.value;
    actualHero[heroId].age = age;
    this.heroes$.next(actualHero);
  }

  getHeroes$(): BehaviorSubject { // To get BehaviorSubject and pass it into ReactJS
    return this.heroes$;
  }
}

然后app.component.ts我们用数据初始化(Zeus和Poseidon):

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  public heroesObj$: BehaviorSubject;
  public heroes: IHero[];

  constructor(private heroService: HeroService) {}

  ngOnInit(): void {
    this.heroService.getHeroes$().subscribe((res: IHero[]) => {
      this.heroes = res;
    });

    this.heroesObj$ = this.heroService.getHeroes$();

    this.initHeroes();
  }

  initHeroes() {
    this.heroService.addHeroes({name: 'Zeus', age: 88});
    this.heroService.addHeroes({name: 'Poseidon', age: 46});
  }
}

在下一步中,我们应该准备应用程序的ReacJS部分,因此我们创建react-bidirectional/react-bidirectional-application.tsx文件:

interface IReactBidirectionalApp {
  injector: Injector;
  heroes$: BehaviorSubject; // We use this interface to grab RxJS object
}

class ReactBidirectionalApp extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      heroes$: this.props.heroes$ // and we pass this data into ReactBidirectionalHero component
    };
  }

  render() {
    return (
      

ReactJS component (bidirectional data binding):

); } } export class ReactBidirectionalApplication { static initialize( containerId: string, injector: Injector, heroes$: BehaviorSubject, // This is necessary to get RxJS object ) { ReactDOM.render( , document.getElementById(containerId) ); } }

在下一步中,我们需要ReactBidirectionalHero组件,因此我们将其创建:

interface IReactBidirectionalHero {
  heroes$: BehaviorSubject;
}

class ReactBidirectionalHero extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      heroes: []
    };

    this.addAge = this.addAge.bind(this); // Register function to bump age
    this.addHero  = this.addHero.bind(this); // Register function to add new Hero
  }

  componentDidMount(): void {
    // In componentDidMount we subscribe heroes$ object
    this.props.heroes$.subscribe((res: IHero[]) => {
      // and we pass this data into React State object
      this.setState({heroes: res});
    });
  }

  addAge(i: number) {
    const temp = this.state.heroes;
    temp[i].age = temp[i].age + 1;

    // In this way we update RxJS object
    this.props.heroes$.next( temp);
  }

  addHero() {
    const temp = this.state.heroes;
    temp.push({name: 'Atena', age: 31});

    // In this way we update RxJS object
    this.props.heroes$.next(temp);
  }

  render() {
    // Hire we render RxJS part of application with addAge button and ADD ATENA button below
    const heroes = this.state.heroes.map((hero: IHero, i) => {
      return {hero.name} - {hero.age} 
; }); return ( react-hero works!
{heroes}
); } } export default ReactBidirectionalHero;

现在我们需要在Angular应用程序中初始化ReactJS应用程序,因此我们可以创建angular/react-bidirectional-renderer.component.ts它-非常简单,与版本相比只有一个更改,而无需通信:

@Component({
  selector: 'app-react-owc-renderer',
  template: `
` }) export class ReactBidirectionalRendererComponent implements OnInit { // Hire we get data from parent component, but of course we can also subscribe this data directly form HeroService if we prefer this way @Input() heroes$: BehaviorSubject; constructor(public injector: Injector) { } ngOnInit() { // We add only one parameter into initialize function ReactBidirectionalApplication.initialize('react-owc-renderer', this.injector, this.heroes$); } }

现在,我们应该进行一些更改ng-hero.component.ts以查看所有效果:

@Component({
  selector: 'app-ng-hero',
  template: `
    
ng-hero works!
{{hero.name}} - {{hero.age}} -

` }) export class NgHeroComponent implements OnInit { public heroes: IHero[]; constructor(private heroService: HeroService) { } ngOnInit() { this.heroService.getHeroes$().subscribe((res: IHero[]) => { this.heroes = res; }); } addAge(heroId: number) { this.heroService.updateHeroAge(heroId, this.heroes[heroId].age + 1); } addHero() { this.heroService.addHeroes({name: 'Afrodita', age: 23}); } }

最后我们改变app.component.html

App.component data:

This is Angular component:



一切都应该工作。如果您有任何问题,请随时提问。

您可以在GitHub上找到此解决方案的完整存储库。

如果您需要演示,请点击雇用。

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有