1

I need to be able to compose an Angular 2 component from several re-usable classes. As such, I'm attempting to implement Mixins using these guides:

https://medium.com/@danny_mylian/mixins-as-class-decorators-in-typescript-angular2-8e09f1bc1f02#.jplhjv33t

https://www.typescriptlang.org/docs/handbook/mixins.html

Here's an abbreviated version of my code. I have multiple mixin classes, so I can't just extend another class:

//date-of-birth-form.ts
export class DateOfBirthForm {
  dobMonth: number = null;
  . . .
}

//registration-form.component.ts
@Component({
  templateUrl: './registration-form.component.html',
})
@Mixin([DateOfBirthForm, ...])
export class RegistrationFormComponent implements DateOfBirthForm {
  . . .
}

the problem I'm getting is:

[ts] Class 'RegistrationFormComponent' incorrectly implements interface 'DateOfBirthForm'. Property 'dobMonth' is missing in type 'RegistrationFormComponent'.

What am I doing wrong? Basically what I need to do is add form groups to a parent form, however some of the form components call web services or call local methods to calculate data that I'd like to encapsulate in the Mixin classes.

Brandon Taylor
  • 33,823
  • 15
  • 104
  • 144

2 Answers2

0

Looking at the example on the page you provided:

@Mixin([Disposable, Activatable])
export class TableViewComponent implements Disposable, Activatable {
   // Disposable
   isDisposed: boolean = false;
   dispose: () => void;
   // Activatable
   isActive: boolean = false;
   activate: () => void;
   deactivate: () => void;
   constructor() {}
}

It looks like this technique requires you to add stubs of the different attributes/methods of the implemented mixins to make the compiler happy.

David M.
  • 2,602
  • 1
  • 15
  • 15
  • I have multiple mixin classes. I'll change my question to reflect that. – Brandon Taylor Nov 23 '16 at 15:29
  • Hmm. When I put in a stub for `dobMonth` in `RegistrationFormComponent` then log it after the class is initialized, it returns `undefined`, even though it has a value in the mixin of `null` (or any other value I set) – Brandon Taylor Nov 23 '16 at 16:44
  • Perhaps there's another way to go about this? My experience with TypeScript is somewhat limited. What I would like to do is extend or implement classes that define all of the properties and method that I want to encapsulate to keep the code dry, then expose those in the parent class. Do I have any other options here? – Brandon Taylor Nov 23 '16 at 16:57
  • Interestingly, I was able to get a property to populate on the parent that was defined on the implemented class, however the data won't bind to the template. If I remove the `implements DateOfBirthForm`, the template is populated as expected. Looks like I might just need to make separate components and stitch them together with state :/ – Brandon Taylor Nov 23 '16 at 19:50
  • Angular 2 components generally favour composition to inheritance... Inheritance can generally be replaced by composition one way or another. Food for thoughts! – David M. Nov 24 '16 at 18:45
0

There are quite a few quirks to "mixins by hand" as described in the links you mention. Missing stubs are just one of them, you'll hit more once you try add private/protected members.

TypeScript 2.2 provides proper Mixin classes that solve many of these issues. I have described how to use them for angular components here:

How to Extend/Inherit Angular2 component?

Community
  • 1
  • 1
Johannes Rudolph
  • 35,298
  • 14
  • 114
  • 172