Reputation: 11
I'm trying to create a custom input text component but I don't know how to make it work with the ngModel
directive.
I've tried replicating the material angular_component input but can't understand how the inputText
property is actually linked to the ngModel
value and what is the purpose of DefaultValueAccessor
directive.
This is how I expect to use my component:
<my-input-component [(ngModel)]="someProp"><my-input-component>
(where the content of my-input-component
is just a plain <input type="text">
field with a label)
Any ideas or links to examples/docs will be greatly appreciated.
Upvotes: 0
Views: 398
Reputation: 11
After debugging the angular_components code, I found the answer myself. You have to implement ControlValueAccessor
and to register the ngValueAccessor
provider (that actually was the missing part).
Here is my solution:
// my_custom_component.dart
@Component(
selector: 'my-custom-component',
templateUrl: '<div class="input-wrapper">{{value}}</div>',
providers: [
ExistingProvider.forToken(ngValueAccessor, MyCustomComponent),
],
)
class MyCustomComponent implements ControlValueAccessor<String> {
String value;
// ...could define a setter that call `_changeController.add(value)`
final _changeController = StreamController<String>();
@Output()
Stream<String> get onChange => _changeController.stream;
@override
void writeValue(String newVal) {
value = newVal ?? '';
}
@override
void registerOnChange(callback) {
onChange.listen((value) => callback(value));
}
// optionally you can implement the rest interface methods
@override
void registerOnTouched(TouchFunction callback) {}
@override
void onDisabledChanged(bool state) {}
}
// app_component.dart
@Component(
selector: 'app-component',
templateUrl: '''
<my-custom-component [(ngModel)]="data"></my-custom-component>
''',
directives: [
NgModel,
MyCustomComponent,
],
)
class AppComponent {
String data;
}
Note: angular_component uses directives but the main idea is the same.
Upvotes: 1