在Angular Component中使用AngularJS指令

时间:2021-10-08 20:07:34

I'm trying to upgrade an angularjs directive to use it my angular component. I've gotten the hybrid (ng1 + ng2) environment to work. I can also inject angularjs services in angular and use them in angular components (I actually got this working even with angularjs 1.4.x).

我正在尝试升级angularjs指令以使用我的角度组件。我已经实现了混合(ng1 + ng2)环境。我也可以在angular中注入angularjs服务并在角度组件中使用它们(我实际上即使使用angularjs 1.4.x也可以使用它)。

Now I'm trying to use an existing angularjs directive in angular, but not working.

现在我试图在角度中使用现有的angularjs指令,但不能正常工作。

For reference, are some snippets of my codes.

作为参考,是我的代码的一些片段。

[index.html] (my-app is the Angular 4 root component)

[index.html](my-app是Angular 4根组件)

...
<body>
    <div class="banner">Angular Migration</div>
    <my-app>Loading...</my-app>
...
</body>
...

[main.ts] (bootstrapping code)

[main.ts](引导代码)

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { UpgradeModule } from '@angular/upgrade/static';
import { Router } from '@angular/router';
import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
  let upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule;
  upgrade.bootstrap(document.documentElement, ['sampleApp']);
  platformRef.injector.get(Router).initialNavigation();
});

[app.module.ts] (Angular 4 module)

[app.module.ts](Angular 4模块)

import { NgModule, Component } from '@angular/core';
import { HashLocationStrategy, LocationStrategy, CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static';
import { RouterModule, Routes, UrlHandlingStrategy } from '@angular/router';

import { HybridUrlHandlingStrategy } from './hybridUrlHandlingStrategy';
import { AppComponent } from './app.component';

export const routes: Routes = [
...
];

@NgModule({
  imports: [
    CommonModule,
    BrowserModule,
    UpgradeModule,
    RouterModule.forRoot([], { useHash: true, initialNavigation: false })
  ],
  providers: [
    { provide: LocationStrategy, useClass: HashLocationStrategy },
    { provide: UrlHandlingStrategy, useClass: HybridUrlHandlingStrategy },
    { provide: 'appService', useFactory: (i: any) => i.get('appService'), deps: ['$injector'] },
    { provide: 'mdToHtml', useFactory: (i: any) => i.get('mdToHtml'), deps: ['$injector'] }
  ],
  declarations: [
    AppComponent
  ],
  bootstrap: [ AppComponent ]    
})
export class AppModule {
  ngDoBootstrap() { }
}

[app.component.ts] (Angular 4 component)

[app.component.ts](Angular 4组件)

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <router-outlet></router-outlet>
    <div ng-view></div>
  `,
})
export class AppComponent { }

[app.js] (AngularJs app)

[app.js](AngularJs app)

'use strict';

angular.module('sampleApp', [
  'ngRoute',
  'app.components.services.appService'
])
  .config(function ($routeProvider) {
    $routeProvider
      .otherwise({
        template: ''
      });
  });

[myStars.js] (AngularJs directive)

[myStars.js](AngularJs指令)

'use strict';

angular.module('app.components.directives.myStars', [])
.controller('MyStarsCtrl', function() {
  console.log("**** in MyStarsCtrl ")
})
.component('myStars', {
  restrict: 'E',
  bindings: {
    count: '=count'
  },
  template: '<div>***** M Y   S T A R S *****</div>'
});

[myStars.ts] (an attempt to migrate myStars directive to Angular 4)

[myStars.ts](尝试将myStars指令迁移到Angular 4)

import { Directive, ElementRef, Injector, Input, Output, EventEmitter } from '@angular/core';
import { UpgradeComponent } from '@angular/upgrade/static';

@Directive({
  selector: 'my-stars'
})
export class MyStarsDirective extends UpgradeComponent {
  @Input() count: number;
  @Output() clicked: EventEmitter<number>;

  constructor(elementRef: ElementRef, injector: Injector) {
    super('myStars', elementRef, injector);
  }
}

[test.module.ts] (Angular 4 test module)

[test.module.ts](Angular 4测试模块)

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes} from '@angular/router';
import { TestComponent } from './test.component';

// importing the new MyStarsDirective)
import { MyStarsDirective } from '../../../components/directives/myStars/myStars';

const thisRoute: Routes = [
    {
        path: 'test/:id',
        component: TestComponent
    }
];

@NgModule({
    declarations: [
        TestComponent,
        MyStarsDirective, // <<<< adding directive here
    ],
    providers: [],
    imports: [
        CommonModule,
        RouterModule.forChild(thisRoute)
    ],
    exports: [
        RouterModule
    ]
})

export class TestModule {}

[test.component.ts] (Angular 4 test component)

[test.component.ts](Angular 4测试组件)

import { Component, Inject, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { HybridUrlHandlingStrategy } from '../../../hybridUrlHandlingStrategy';
import { MyStarsDirective } from '../../../components/directives/myStars/myStars';

@Component({
  templateUrl: './test.component.html'
})
export class TestComponent implements OnInit {
  routeParams: any
  myService: any
  mdToHtml: any

  constructor(
    @Inject('myService') myService: any,
    @Inject('mdToHtml') mdToHtml: (str: string) => string,
    private activatedRoute: ActivatedRoute
  ) {
    this.myService = myService;
    this.mdToHtml = mdToHtml;
  }
  ngOnInit() {
    this.routeParams = this.activatedRoute.params.subscribe(params => {
      console.log("params", params['groupId'])
...
  }
  ngOnDestroy() {
    this.routeParams.unsubscribe();
  }
}

[test.component.html] (Angular 4 html)

[test.component.html](Angular 4 html)

...
<my-stars></my-stars>      <!-- <<<< using directive here -->
...

Note: I've also upgrade angularjs version to 1.5 just to make this hybrid app works.

注意:我还将angularjs版本升级到1.5只是为了使这个混合应用程序正常工作。

Here's the error when I browser the test component page:

这是浏览测试组件页面时的错误:

在Angular Component中使用AngularJS指令

Any help would be greatly appreciated.

任何帮助将不胜感激。

Thanks.

1 个解决方案

#1


8  

For anyone interested, here's the solution to this error.

对于任何感兴趣的人,这里是这个错误的解决方案。

[test.module.ts] (Angular 4 test module)

[test.module.ts](Angular 4测试模块)

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes} from '@angular/router';
import { TestComponent } from './test.component';

// importing the new MyStarsDirective)
import { MyStarsDirective } from '../../../components/directives/myStars/myStars';

const thisRoute: Routes = [
    {
        path: 'test/:id',
        component: TestComponent
    }
];

@NgModule({
    declarations: [
        TestComponent,
        MyStarsDirective, // <<<< adding directive here
    ],
    providers: [
        {
            provide: '$scope',
            useFactory: i => i.get('$rootScope'),
            deps: ['$injector']
        }, // <<<< added this section to fix the No provider for $scope error
    ],
    imports: [
        CommonModule,
        RouterModule.forChild(thisRoute)
    ],
    exports: [
        RouterModule
    ]
})

export class TestModule {}

I found the answer in this link https://github.com/angular/angular/issues/14993 (inspired by BrunoPoeta) See comment by gkalpak on March 10.

我在这个链接中找到了答案https://github.com/angular/angular/issues/14993(灵感来自BrunoPoeta)请参阅gkalpak于3月10日发表的评论。

Now let's see if I can upgrade a regular directive and use 1.4.x.

现在让我们看看我是否可以升级常规指令并使用1.4.x.

#1


8  

For anyone interested, here's the solution to this error.

对于任何感兴趣的人,这里是这个错误的解决方案。

[test.module.ts] (Angular 4 test module)

[test.module.ts](Angular 4测试模块)

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes} from '@angular/router';
import { TestComponent } from './test.component';

// importing the new MyStarsDirective)
import { MyStarsDirective } from '../../../components/directives/myStars/myStars';

const thisRoute: Routes = [
    {
        path: 'test/:id',
        component: TestComponent
    }
];

@NgModule({
    declarations: [
        TestComponent,
        MyStarsDirective, // <<<< adding directive here
    ],
    providers: [
        {
            provide: '$scope',
            useFactory: i => i.get('$rootScope'),
            deps: ['$injector']
        }, // <<<< added this section to fix the No provider for $scope error
    ],
    imports: [
        CommonModule,
        RouterModule.forChild(thisRoute)
    ],
    exports: [
        RouterModule
    ]
})

export class TestModule {}

I found the answer in this link https://github.com/angular/angular/issues/14993 (inspired by BrunoPoeta) See comment by gkalpak on March 10.

我在这个链接中找到了答案https://github.com/angular/angular/issues/14993(灵感来自BrunoPoeta)请参阅gkalpak于3月10日发表的评论。

Now let's see if I can upgrade a regular directive and use 1.4.x.

现在让我们看看我是否可以升级常规指令并使用1.4.x.