【问题标题】:how to override directive definitions in angular 2如何覆盖角度2中的指令定义
【发布时间】:2016-01-28 08:54:38
【问题描述】:

可以在 Angular 1 中装饰(覆盖)指令定义。

这里有解释:http://www.bennadel.com/blog/2926-overriding-directive-definitions-in-angularjs.htm

有一个内置函数

angular.module( "X" ).decorator(

为此。

在 angular2 中,我们没有模块。推荐的方法是使用 typescript 模块。

如何在 angular2 中装饰(覆盖)指令?

我想这样做的主要原因是为了自定义,当我在几个站点中部署我的应用程序时。

假设我的所有应用程序都有一个 bundle.js,然后我只想放入一个带有大量自定义项的 customer.js,而不是为每个站点部署更改和重建我现有的 bundle.js。

让我们添加一个英雄之旅的具体例子: 我在 javascript 文件中定义了我的应用组件:

import {Component, OnInit} from 'angular2/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
import {HeroService} from './hero.service';

@Component({
  selector: 'my-app',
  template:`
    <h1>{{title}}</h1>
    <h2>My Heroes</h2>
    <ul class="heroes">
      <li *ngFor="#hero of heroes"
        [class.selected]="hero === selectedHero"
        (click)="onSelect(hero)">
        <span class="badge">{{hero.id}}</span> {{hero.name}}
      </li>
    </ul>
    <my-hero-detail [hero]="selectedHero"></my-hero-detail>
  `,

  directives: [HeroDetailComponent],
  providers: [HeroService]
})

我希望能够在另一个 javascript 文件中将 HeroDetailComponent 与另一个组件 CustomHeroDetailComponent 进行切换。

这怎么可能?

【问题讨论】:

    标签: angular


    【解决方案1】:

    没有对此 AFAIK 的直接支持。 我猜底层问题与https://github.com/angular/angular/issues/5622

    相同

    作为一种可能的解决方法,您可以创建一个导出所有组件的文件,并在从那里导入的组件源文件中; 然后,您可以通过替换此导出文件来更改绑定。

    这很丑,因为所有组件都依赖于该全局文件。

    【讨论】:

      【解决方案2】:

      我做了类似于动态加载自定义模块并为 POC 配置 RouteConfig 注释的操作。要从脚本中导入脚本文件,我们需要使用动态模块加载器 - Systemjs。看看这个Lazy loading example

      要动态加载组件,您可以使用示例中详细说明的虚拟代理。

      directives: [componentProxyFactory({'compName':'CustomHeroDetailComponent'})],
      

      对于虚拟代理 -

      export class ComponentProvider {
          compName:string;
      }
      
      export class ComponentDetail {
          path: string;
          name: string;
      }
      
      @Injectable()
      export class DynamicComponentLoaderService
      {
         //implement component lookup logic
          getComponentDetail(compName: string):ComponentDetail{
              return {'path':'./path/to/comp/custom.herodetail.component', 'name':'CustomHeroDetailComponent'};
          }    
      }
      
      export function componentProxyFactory(provider: ComponentProvider): Type {
          @Component({
              selector: 'component-proxy',
              template: `<span #content></span>`,
              providers: [provide(ComponentProvider, { useValue: provider})]
          })
          class VirtualComponent {
              constructor(el: ElementRef,loader:DynamicComponentLoader, inj:Injector, _service: DynamicComponentLoaderService, provider:ComponentProvider)
              {
                  var compDetail = _service.getComponentDetail(provider.compName);
                  System.import(compDetail.path)
                      .then(m => {
                          loader.loadIntoLocation(m[compDetail.name], el, 'content');
                      });
              }
          }
          return VirtualComponent;
      }
      

      希望这是您正在寻找的。

      【讨论】:

      • 我确实在寻找更好的解决方案,但我想这是最好的解决方案。
      • 到目前为止我也找不到。将保持此帖子更新。
      【解决方案3】:

      尝试使用以下代码。

          import {HeroDetailComponent} from './hero-detail.component';
      
      
              @Component({
                selector: 'custom-hero-detail',
                template:`
                  <hero-detail param="...">
                `,
                directives: [HeroDetailComponent],
              })
              export class CustomHeroDetailComponent extends HeroDetailComponent{
                // custom code.
              }
      

      您可以扩展组件并在您的内部使用该指令。

      【讨论】:

      • 如何扩展多个指令? Angular 团队会实现这个吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-30
      • 2016-09-19
      • 2017-11-11
      • 1970-01-01
      • 2016-03-01
      • 2017-09-27
      • 2015-08-20
      相关资源
      最近更新 更多