问题
I have a button component (with app specific behavior) that i intended to use widely in the app. The issue is that when I have a parent/child views where I use this button, a click on the paren't button triggers the [action] of the child's view button : naturally you don't get what's happening if you don't have some years of object oriented programming. (which is pretty a bad point to get young school novices to use dart...)
Just to explain the problem : each component in dart is a singleton in its scope (the scope being different for each tree node, except for the parent/child relationship). This is a good optimisation practice, but I think there should be a mandatory attribute to the component that takes the values
scope="prototype|optimized"
This will iblige novices to understand the concepts behind it...
Is there a solution to get a new instance for each DI injection?
This is the code:
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();
}
}
Then I use this button in many places (knowing I can make it evolve through the app life)
For example
@Component(
selector: 'users-comp',
templateUrl: 'users_comp.html',
styleUrls: const ['users_comp.css'],
directives: const[ButtonComp, TextComp, InviteUsersDialogComp]
)
class UsersComp implements OnInit {
//...
}
If I have two buttons in UsersComp or one button in UsersComp and one in any of its children, then I will get the same instance of the button everywhere : I noticed that because clicking on the button of UsersComp triggered the 'action' of its subcomponents
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>
and invite-dialog-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>
get the same button
回答1:
With this provider
provide('myFactory', useFactory: (dep1, dep2) => () => new Foo(dep1, dep2), deps: [Dep1, Dep2])
you can create new instances like
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;
}
}
}
来源:https://stackoverflow.com/questions/41761885/how-do-i-use-a-component-twice-in-a-prent-and-child-views-di-is-shared-and-the