2017-02-15 3 views
0

Я пытаюсь создать директиву с контроллером с использованием Angular 1.5 и TypeScript 1.8, но это не сработает для меня. Я посмотрел на кучу примеров, но я следую этим примерам в тройник, и это все равно не сработает для меня. Я проклят?Угловая директива 1.5 + TypeScript с контроллером

Вот код:

export class FooController implements angular.IController { 
    static $inject = ['myService', '$state']; 

    constructor(private myService: Services.MyService, private $state: angular.ui.IStateService) { 
    } 

    public foo: Services.Dtos.Foo; 
    public bar; 

    $onInit() { 
     if (!this.foo) return; 

     this.bar = this.$state.href('app.bar', {id: this.foo.id}); 
    } 
} 

export class FooDirective implements angular.IDirective { 
    public restrict = 'E'; 
    public replace = true; 
    public scope = {}; 
    public templateUrl = 'content/templates/foo.template.html'; 
    public controller = FooController; 
    public controllerAs = 'ctrl'; 
    public bindToController = { 
     foo: '<', 
    }; 
} 

Она ошибки на FooDirective говорят следующее:

  1. Класс 'FooDirective' неправильно 'реализует интерфейс IDirective.
  2. Типы собственности «bindToController» несовместимы.
  3. Тип '{foo: string; } 'не присваивается type' boolean | {[boundProperty: string]: string; }».
  4. Тип '{foo: string; } 'не присваивается типу' {[boundProperty: string]: string; }».
  5. Недопустимая подпись подписи '{foo: string; }».

Что я делаю неправильно?

UPDATE 2017/02/15 IDirective выглядит следующим образом (из angular.d.ts файла):

interface IDirective { 
    compile?: IDirectiveCompileFn; 
    controller?: string | Injectable<IControllerConstructor>; 
    controllerAs?: string; 
    /** 
    * @deprecated 
    * Deprecation warning: although bindings for non-ES6 class controllers are currently bound to this before 
    * the controller constructor is called, this use is now deprecated. Please place initialization code that 
    * relies upon bindings inside a $onInit method on the controller, instead. 
    */ 
    bindToController?: boolean | {[boundProperty: string]: string}; 
    link?: IDirectiveLinkFn | IDirectivePrePost; 
    multiElement?: boolean; 
    priority?: number; 
    /** 
    * @deprecated 
    */ 
    replace?: boolean; 
    require?: string | string[] | {[controller: string]: string}; 
    restrict?: string; 
    scope?: boolean | {[boundProperty: string]: string}; 
    template?: string | ((tElement: JQuery, tAttrs: IAttributes) => string); 
    templateNamespace?: string; 
    templateUrl?: string | ((tElement: JQuery, tAttrs: IAttributes) => string); 
    terminal?: boolean; 
    transclude?: boolean | 'element' | {[slot: string]: string}; 
} 
+0

Я скопировал ваш код в проект Angular и не получил ошибку. Какие типизации для 'IDirective' вы используете? Пожалуйста, добавьте их на свой вопрос. –

+0

@ Сабастин, я добавил тимпинг. Это очень озадачивает меня. Я не уверен, почему это не работает. –

+0

В соответствии с этим: http://stackoverflow.com/questions/22077023/why-cant-i-indirectly-return-an-object-literal-to-satisfy-an-index-signature- это решение явно cast scope и bindToController к '{[boundProperty: string]: string}', и ошибка исчезнет. –

ответ

1

директива должна быть функция, которая возвращает объект конфигурации. Я бы написал директиву следующим образом:

export const fooDirective =(): angular.IDirective => { 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: {}, 
     templateUrl: 'content/templates/foo.template.html', 
     controller: FooController, 
     controllerAs: 'ctrl', 
     bindToController: { 
      foo: '<' 
     } 
    }; 
}; 

Я бы также рекомендовал вам взглянуть на новый компонентный API. Это значительно упрощает создание новых компонентов, и по умолчанию используется множество передовых методов, таких как controllerAs.

https://docs.angularjs.org/guide/directive
https://docs.angularjs.org/guide/component

+0

Этот ответ не помогает вообще. Проблема заключается в том, что TypeScript жалуется на то, что мой 'bindToController' не прав. Я не уверен, что происходит. –

0

Казалось бы, проблема с определением машинопись только принимать логическое значение.

export class FooDirective implements angular.IDirective { 
    public restrict = 'E'; 
    public replace = true; 
    public scope = {}; 
    public templateUrl = 'content/templates/foo.template.html'; 
    public controller = FooController; 
    public controllerAs = 'ctrl'; 
    public bindToController:any = { 
     foo: '<', 
    }; 
} 

Это исправит ошибку, с другой стороны, это не будет typecheck bindToController.

+0

Вам не нужно писать слово 'public' семь (7) раз, оно не влияет на ваш код, кроме случаев, когда оно уменьшает читаемость. –

Смежные вопросы