Подтвердить что ты не робот

Как переопределить определения директив в angular 2

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

Как это возможно?

4b9b3361

Ответ 1

Я сделал что-то похожее на динамическую загрузку настраиваемого модуля и настроил аннотацию RouteConfig для POC. Чтобы импортировать файл script из script, нам нужно использовать загрузчик динамического модуля - Systemjs. Взгляните на Lazy пример загрузки

Чтобы загрузить динамическую компоненту компонента, вы можете использовать виртуальный прокси, как описано в примере.

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;
}

Надеюсь, это то, что вы ищете.

Ответ 2

Прямой поддержки для этого AFAIK нет. Я предполагаю, что проблема с подстиланием такая же, как https://github.com/angular/angular/issues/5622

В качестве возможного обходного пути вы можете создать файл, который экспортирует все ваши компоненты и в исходный файл компонента, который вы импортируете; Затем вы можете изменить привязки, заменив этот файл экспорта.

Это уродливо, потому что все компоненты запускаются в зависимости от этого глобального файла.

Ответ 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.
        }

Вы можете расширить компонент и использовать эту директиву внутри своего.