如何在一个prent和子视图中使用一个组件两次(DI是共享的,comp是一个单例) [英] How do I use a component twice in a prent and child views (DI is shared and the comp is a singleton)

查看:161
本文介绍了如何在一个prent和子视图中使用一个组件两次(DI是共享的,comp是一个单例)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个按钮组件(与应用程序特定的行为),我打算在应用程序中广泛使用。问题是,当我有一个父/子视图,我使用这个按钮,点击paren't按钮触发孩子的视图按钮的[动作]:自然你不会得到发生了什么,如果你不有一些年的面向对象编程。 (这是一个坏点,让年轻的学校新手使用dart ...)



只是为了解释问题:dart中的每个组件是一个单例的范围(每个树节点的范围不同,除了父/子关系之外)。这是一个很好的优化实践,但我认为应该有一个强制属性的组件取值

  scope =原型|优化

这将使新手懂得背后的概念...



有没有解决方案,为每个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;
函数btnAction;
List< String> _srcList;
@Input()bool disabled;

@Input()
void set sources(List< String> srcList){
if(srcList?.length!= 3)
print为$ {btnAction.toString()}');为$ {srcList?.toString()}为状态的3个文件:默认,悬停和点击。
_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按钮上触发其子组件的动作



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>人< / div>




b $ b 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>

获得相同的按钮

方案

使用此提供者

 提供('myFactory',useFactory:(dep1,dep2)=> ;()=> new Foo(dep1,dep2),deps:[Dep1,Dep2])

您可以创建新实例

 类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;
}
}
}


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

解决方案

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;
    }
  }
}

这篇关于如何在一个prent和子视图中使用一个组件两次(DI是共享的,comp是一个单例)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆