在 Angular 组件中使用 AngularJS 指令 [英] Use AngularJS directive in Angular Component

查看:32
本文介绍了在 Angular 组件中使用 AngularJS 指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试升级 angularjs 指令以将其用于我的 angular 组件.我已经使用了混合 (ng1 + ng2) 环境.我还可以在 angular 中注入 angularjs 服务,并在 angular 组件中使用它们(我实际上在使用 angularjs 1.4.x 时也能正常工作).

现在我正在尝试在 angular 中使用现有的 angularjs 指令,但不起作用.

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

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

<预><代码>...<身体><div class="banner">Angular Migration</div><my-app>正在加载...</my-app>......

[main.ts](引导代码)

import { platformBrowserDynamic } from '@angular/platform-b​​rowser-dynamic';从'@angular/upgrade/static' 导入 { UpgradeModule };从@angular/router"导入{路由器};从 './app.module' 导入 { AppModule };platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {让 upgrade = platformRef.injector.get(UpgradeModule) 作为 UpgradeModule;upgrade.bootstrap(document.documentElement, ['sampleApp']);platformRef.injector.get(Router).initialNavigation();});

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

import { NgModule, Component } from '@angular/core';从@angular/common"导入 { HashLocationStrategy, LocationStrategy, CommonModule };从'@angular/platform-b​​rowser' 导入 { BrowserModule };从'@angular/upgrade/static' 导入 { UpgradeModule };从@angular/router"导入 { RouterModule, Routes, UrlHandlingStrategy };从'./hybridUrlHandlingStrategy'导入{HybridUrlHandlingStrategy};从 './app.component' 导入 { AppComponent };导出常量路由:路由 = [...];@NgModule({进口:[通用模块,浏览器模块,升级模块,RouterModule.forRoot([], { useHash: true, initialNavigation: false })],供应商: [{提供:LocationStrategy,useClass:HashLocationStrategy},{ 提供: UrlHandlingStrategy, useClass: HybridUrlHandlingStrategy },{提供:'appService',useFactory:(i:任何)=>i.get('appService'), deps: ['$injector'] },{提供:'mdToHtml',useFactory:(i:任何)=>i.get('mdToHtml'), deps: ['$injector'] }],声明: [应用组件],引导程序:[ AppComponent ]})导出类 AppModule {ngDoBootstrap() { }}

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

import { Component } from '@angular/core';@成分({选择器:'我的应用',模板:`<路由器插座></路由器插座><div ng-view></div>`,})导出类 AppComponent { }

[app.js](AngularJs 应用)

'use strict';angular.module('sampleApp', ['ngRoute','app.components.services.appService']).config(function ($routeProvider) {$routeProvider.除此以外({模板: ''});});

[myStars.js](AngularJs 指令)

'use strict';angular.module('app.components.directives.myStars', []).controller('MyStarsCtrl', function() {console.log("**** 在 MyStarsCtrl 中")}).component('myStars', {限制:'E',绑定:{计数:'=计数'},模板:'<div>***** M Y S T A R S *****</div>'});

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

import { Directive, ElementRef, Injector, Input, Output, EventEmitter } from '@angular/core';从'@angular/upgrade/static'导入{升级组件};@指示({选择器:'我的星星'})导出类 MyStarsDirective 扩展了 UpgradeComponent {@Input() 计数:数量;@Output() 点击:EventEmitter;构造函数(元素引用:元素引用,注入器:注入器){super('myStars', elementRef, 注入器);}}

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

import { NgModule } from '@angular/core';从'@angular/common'导入{CommonModule};从'@angular/router' 导入 { RouterModule, Routes};从 './test.component' 导入 { TestComponent };//导入新的 MyStarsDirective)从'../../../components/directives/myStars/myStars'导入{MyStarsDirective};const thisRoute: 路由 = [{路径:'测试/:id',组件:测试组件}];@NgModule({声明: [测试组件,MyStarsDirective,//<<<<在此处添加指令],提供者:[],进口:[通用模块,RouterModule.forChild(thisRoute)],出口:[路由器模块]})导出类 TestModule {}

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

import { Component, Inject, OnInit } from '@angular/core';从@angular/router"导入{ActivatedRoute};从'@angular/forms'导入{FormsModule};从'../../../hybridUrlHandlingStrategy'导入{HybridUrlHandlingStrategy};从'../../../components/directives/myStars/myStars'导入{MyStarsDirective};@成分({templateUrl: './test.component.html'})导出类 TestComponent 实现 OnInit {路线参数:任何我的服务:任何mdToHtml: 任何构造函数(@Inject('myService') myService: 任何,@Inject('mdToHtml') mdToHtml: (str: string) =>细绳,私人激活路由: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)

<预><代码>...<my-stars></my-stars><!-- <<<<在此处使用指令 -->...

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

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

任何帮助将不胜感激.

谢谢.

解决方案

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

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

import { NgModule } from '@angular/core';从'@angular/common'导入{CommonModule};从'@angular/router' 导入 { RouterModule, Routes};从 './test.component' 导入 { TestComponent };//导入新的 MyStarsDirective)从'../../../components/directives/myStars/myStars'导入{MyStarsDirective};const thisRoute: 路由 = [{路径:'测试/:id',组件:测试组件}];@NgModule({声明: [测试组件,MyStarsDirective,//<<<<在此处添加指令],供应商: [{提供:'$scope',使用工厂:我 =>i.get('$rootScope'),deps: ['$injector']},//<<<<添加此部分以修复 No provider for $scope 错误],进口:[通用模块,RouterModule.forChild(thisRoute)],出口:[路由器模块]})导出类 TestModule {}

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

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

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).

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

For reference, are some snippets of my codes.

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

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

[main.ts] (bootstrapping code)

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)

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)

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)

'use strict';

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

[myStars.js] (AngularJs directive)

'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)

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)

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)

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)

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

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

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

Any help would be greatly appreciated.

Thanks.

解决方案

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

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

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.

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

这篇关于在 Angular 组件中使用 AngularJS 指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆