为 material-dropdown-select 明确指定类型而不是动态
Explicitly specify type for material-dropdown-select instead of dynamic
任务
在 AngularDart 中,我想通过 material-dropdown-select
选择多个 Foo
对象,并以反应形式存储选定的值。
我的做法
import 'package:angular/angular.dart';
import 'package:angular_components/angular_components.dart';
import 'package:angular_forms/angular_forms.dart';
@Component(
selector: 'my-app',
template: '''
<form [ngFormModel]="form">
<material-dropdown-select
multi
ngControl="control1"
[options]="options"
[itemRenderer]="renderer"
>
</material-dropdown-select>
</form>
''',
directives: [
formDirectives,
MaterialDropdownSelectComponent,
MultiDropdownSelectValueAccessor,
],
providers: [
materialProviders,
],
)
class AppComponent {
var options = SelectionOptions.fromList([Foo(50, 'op1'), Foo(51, 'op2'), Foo(52, 'op3')]);
var form;
AppComponent() {
form = ControlGroup({
'control1': Control<List<Foo>>(<Foo>[]),
});
}
String renderer(Foo entry) => '${entry.id}: ${entry.title}';
}
class Foo {
int id;
String title;
Foo(this.id, this.title);
}
问题
由于模板代码出现异常,无法应用我的自定义渲染器:
EXCEPTION: Expected a value of type '(dynamic) => String', but got one of type '(Foo) => String'
dynamic
从哪里出现的?我认为值访问器将从 options
中获取 Foo
类型!如果没有该渲染器,组件会出现,但选择任何项目都会抛出下一个:
Error: Type 'List<dynamic>' should be 'List<Foo>' to implement expected type 'List<Foo>'.
它从 material_dropdown_material_accessor.dart 文件中抛出,MultiDropdownSelectValueAccessor
class:
@override
void registerOnChange(callback) {
selectionChangesSub = selectionModel.selectionChanges.listen((_) {
callback(selectionModel.selectedValues?.toList());
});
}
再一次 - dynamic
出现在哪里?将 material 下拉菜单与自定义类型一起使用是真的吗?
我想 MultiDropdownSelectValueAccessor
实现了 ControlValueAccessor<List<dynamic>>
。可能您必须实现自己的值访问器,例如:
@Directive(
selector : 'you-must-set-correct-selector-here`
)
class FooMultiDropdownSelectValueAccessor implements ControlValueAccessor<List<Foo>> {
...
}
选择器可以引入一些属性,例如[list-type=foo]
根本原因
问题在于 MaterialDropdownSelectComponent<T>
和 MultiDropdownSelectValueAccessor<T>
是通用指令 。 T
默认为 dynamic
。
解决方案
有一个实验性的 AngularDart 功能 — directiveTypes
。它允许为组件模板中的任何指令指定通用类型。在我的例子中,缺少的行如下:
@Component(
...
directiveTypes: [
Typed<MaterialDropdownSelectComponent<Foo>>(),
Typed<MultiDropdownSelectValueAccessor<Foo>>(),
],
)
class AppComponent {
...
}
我在 GitHub issue. It's curious what TypeScript users do for working around that 上偶然发现了它。
任务
在 AngularDart 中,我想通过 material-dropdown-select
选择多个 Foo
对象,并以反应形式存储选定的值。
我的做法
import 'package:angular/angular.dart';
import 'package:angular_components/angular_components.dart';
import 'package:angular_forms/angular_forms.dart';
@Component(
selector: 'my-app',
template: '''
<form [ngFormModel]="form">
<material-dropdown-select
multi
ngControl="control1"
[options]="options"
[itemRenderer]="renderer"
>
</material-dropdown-select>
</form>
''',
directives: [
formDirectives,
MaterialDropdownSelectComponent,
MultiDropdownSelectValueAccessor,
],
providers: [
materialProviders,
],
)
class AppComponent {
var options = SelectionOptions.fromList([Foo(50, 'op1'), Foo(51, 'op2'), Foo(52, 'op3')]);
var form;
AppComponent() {
form = ControlGroup({
'control1': Control<List<Foo>>(<Foo>[]),
});
}
String renderer(Foo entry) => '${entry.id}: ${entry.title}';
}
class Foo {
int id;
String title;
Foo(this.id, this.title);
}
问题
由于模板代码出现异常,无法应用我的自定义渲染器:
EXCEPTION: Expected a value of type '(dynamic) => String', but got one of type '(Foo) => String'
dynamic
从哪里出现的?我认为值访问器将从 options
中获取 Foo
类型!如果没有该渲染器,组件会出现,但选择任何项目都会抛出下一个:
Error: Type 'List<dynamic>' should be 'List<Foo>' to implement expected type 'List<Foo>'.
它从 material_dropdown_material_accessor.dart 文件中抛出,MultiDropdownSelectValueAccessor
class:
@override
void registerOnChange(callback) {
selectionChangesSub = selectionModel.selectionChanges.listen((_) {
callback(selectionModel.selectedValues?.toList());
});
}
再一次 - dynamic
出现在哪里?将 material 下拉菜单与自定义类型一起使用是真的吗?
我想 MultiDropdownSelectValueAccessor
实现了 ControlValueAccessor<List<dynamic>>
。可能您必须实现自己的值访问器,例如:
@Directive(
selector : 'you-must-set-correct-selector-here`
)
class FooMultiDropdownSelectValueAccessor implements ControlValueAccessor<List<Foo>> {
...
}
选择器可以引入一些属性,例如[list-type=foo]
根本原因
问题在于 MaterialDropdownSelectComponent<T>
和 MultiDropdownSelectValueAccessor<T>
是通用指令 。 T
默认为 dynamic
。
解决方案
有一个实验性的 AngularDart 功能 — directiveTypes
。它允许为组件模板中的任何指令指定通用类型。在我的例子中,缺少的行如下:
@Component(
...
directiveTypes: [
Typed<MaterialDropdownSelectComponent<Foo>>(),
Typed<MultiDropdownSelectValueAccessor<Foo>>(),
],
)
class AppComponent {
...
}
我在 GitHub issue. It's curious what TypeScript users do for working around that 上偶然发现了它。