如何在父视图和子视图中两次使用一个组件(DI 是共享的,comp 是单例的)
How do I use a component twice in a prent and child views (DI is shared and the comp is a singleton)
我有一个按钮组件(具有特定于应用程序的行为),我打算在应用程序中广泛使用它。问题是,当我在使用此按钮的地方有 parent/child 视图时,单击父按钮会触发子视图按钮的 [action] :如果您不这样做,您自然不会明白发生了什么'有多年的面向对象编程经验。 (让年轻的学校新手使用飞镖是非常糟糕的一点......)
只是为了解释这个问题:dart 中的每个组件在其范围内都是一个单例(每个树节点的范围不同,parent/child 关系除外)。这是一个很好的优化实践,但我认为取值
的组件应该有一个强制属性
scope="prototype|optimized"
这将使新手理解其背后的概念...
是否有为每次 DI 注入获取新实例的解决方案?
这是代码:
button.html
<img src="{{src}}" (click)="click()" (mouseover)="hover()" (mouseleave)="blur()" class="imgBtn" />
button.dart
import 'package:angular2/core.dart';
@Component(
selector: 'btn',
templateUrl: 'button_comp.html',
styleUrls: const['button_comp.css']
)
class ButtonComp {
String src;
Function btnAction;
List<String> _srcList;
@Input() bool disabled;
@Input()
void set sources(List<String> srcList) {
if( srcList?.length != 3)
print( 'there must be 3 files for the states : default, hover and clicked. Found : ${srcList?.toString()} for ${btnAction.toString()}' );
_srcList = srcList;
src = srcList == null ? 'invalidState' : srcList[0];
}
@Input() set action(Function btnAction) {
this.btnAction = btnAction;
}
void hover() {
src = _srcList[1];
}
void blur() {
src = _srcList[0];
}
void click() {
src = _srcList[2];
if( btnAction != null )
this?.btnAction();
}
}
然后我在很多地方使用这个按钮(知道我可以让它在应用程序生命周期中进化)
例如
@Component(
selector: 'users-comp',
templateUrl: 'users_comp.html',
styleUrls: const ['users_comp.css'],
directives: const[ButtonComp, TextComp, InviteUsersDialogComp]
)
class UsersComp implements OnInit {
//...
}
如果我在 UsersComp 中有两个按钮,或者在 UsersComp 中有一个按钮,在它的任何一个子项中有一个按钮,那么我将在任何地方得到相同的按钮实例:我注意到因为点击 UsersComp 的按钮触发了 'action' 的子组件
users_comp.html
<div class="titleDiv">
<btn [action]="add"
[sources]="['../images/addPerson.bmp', '../images/addPerson-h.bmp', '../images/addPerson-c.bmp']"
class="addBtn"></btn>
<div class="title">people</div>
和
邀请对话-comp.html
<div class="modal-footer">
<btn [action]="save(search.value)" [sources]="['../images/ok.bmp', '../images/ok-h.bmp', '../images/ok-c.bmp']" class="saveAdd"></btn>
</div>
获得相同的按钮
使用此提供商
provide('myFactory', useFactory: (dep1, dep2) => () => new Foo(dep1, dep2), deps: [Dep1, Dep2])
您可以创建新实例,例如
class MyComponent {
MyClass(@Inject('myFactory') Function myFactory) {
var prevInstance;
for(var i = 0; i < 5; i++) {
var newInstance = myFactory();
print('$i: ${identical(newInstance, prevInstance)}');
prevInstance = newInstance;
}
}
}
我有一个按钮组件(具有特定于应用程序的行为),我打算在应用程序中广泛使用它。问题是,当我在使用此按钮的地方有 parent/child 视图时,单击父按钮会触发子视图按钮的 [action] :如果您不这样做,您自然不会明白发生了什么'有多年的面向对象编程经验。 (让年轻的学校新手使用飞镖是非常糟糕的一点......)
只是为了解释这个问题:dart 中的每个组件在其范围内都是一个单例(每个树节点的范围不同,parent/child 关系除外)。这是一个很好的优化实践,但我认为取值
的组件应该有一个强制属性scope="prototype|optimized"
这将使新手理解其背后的概念...
是否有为每次 DI 注入获取新实例的解决方案?
这是代码:
button.html
<img src="{{src}}" (click)="click()" (mouseover)="hover()" (mouseleave)="blur()" class="imgBtn" />
button.dart
import 'package:angular2/core.dart';
@Component(
selector: 'btn',
templateUrl: 'button_comp.html',
styleUrls: const['button_comp.css']
)
class ButtonComp {
String src;
Function btnAction;
List<String> _srcList;
@Input() bool disabled;
@Input()
void set sources(List<String> srcList) {
if( srcList?.length != 3)
print( 'there must be 3 files for the states : default, hover and clicked. Found : ${srcList?.toString()} for ${btnAction.toString()}' );
_srcList = srcList;
src = srcList == null ? 'invalidState' : srcList[0];
}
@Input() set action(Function btnAction) {
this.btnAction = btnAction;
}
void hover() {
src = _srcList[1];
}
void blur() {
src = _srcList[0];
}
void click() {
src = _srcList[2];
if( btnAction != null )
this?.btnAction();
}
}
然后我在很多地方使用这个按钮(知道我可以让它在应用程序生命周期中进化)
例如
@Component(
selector: 'users-comp',
templateUrl: 'users_comp.html',
styleUrls: const ['users_comp.css'],
directives: const[ButtonComp, TextComp, InviteUsersDialogComp]
)
class UsersComp implements OnInit {
//...
}
如果我在 UsersComp 中有两个按钮,或者在 UsersComp 中有一个按钮,在它的任何一个子项中有一个按钮,那么我将在任何地方得到相同的按钮实例:我注意到因为点击 UsersComp 的按钮触发了 'action' 的子组件
users_comp.html
<div class="titleDiv">
<btn [action]="add"
[sources]="['../images/addPerson.bmp', '../images/addPerson-h.bmp', '../images/addPerson-c.bmp']"
class="addBtn"></btn>
<div class="title">people</div>
和 邀请对话-comp.html
<div class="modal-footer">
<btn [action]="save(search.value)" [sources]="['../images/ok.bmp', '../images/ok-h.bmp', '../images/ok-c.bmp']" class="saveAdd"></btn>
</div>
获得相同的按钮
使用此提供商
provide('myFactory', useFactory: (dep1, dep2) => () => new Foo(dep1, dep2), deps: [Dep1, Dep2])
您可以创建新实例,例如
class MyComponent {
MyClass(@Inject('myFactory') Function myFactory) {
var prevInstance;
for(var i = 0; i < 5; i++) {
var newInstance = myFactory();
print('$i: ${identical(newInstance, prevInstance)}');
prevInstance = newInstance;
}
}
}