模板中的Angular 2重复组件引用另一个元素

时间:2017-05-19 11:00:38

标签: angular templates typescript components generic-programming

简化我有一个可以在任何模板中多次使用的组件。如何让我的组件 click-me 与它下面的输入元素配对,这样当事件(在这种情况下单击)被触发时它将应用(在这种情况下将输入类型更改为隐藏)对那个输入。显然,这种方法很重要,而不是隐藏!

  

我可以添加哪些内容来保持重复组件的通用性和自主性?

enter image description here

<div>
  <click-me></click-me>
  <input type="input" value="friend 2 to hide" id="clickme1">
</div>

<div>
  <click-me></click-me>
  <input type="input" value="friend 2 to hide" id="clickme2">
</div>

COMPONENT

 public class LoginActivity extends Activity {

    Button pwrecovery;
    Context context = getApplicationContext();
    CharSequence text ="hello toast!";
    int duration = Toast.LENGTH_LONG;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //set up notitle
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //set up full screen
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_login);

    pwrecovery=(Button) findViewById(R.id.pwrecovery);
        pwrecovery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
        });

TEMPLATE

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".LoginActivity"
    android:orientation="vertical"
    android:background="@color/blue">


    <ImageView
        android:layout_width="99dp"
        android:layout_height="91dp"
        android:id="@+id/imageView"
        android:src="@drawable/logo"
        android:layout_gravity="center"
        android:background="#02496b"
        android:layout_marginTop="10dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/quote_eng"
        android:id="@+id/textView"
        android:layout_gravity="center"
        android:layout_marginTop="15dp"
        android:singleLine="true"
        android:textColor="#ffffffff" />



    <EditText
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress"
        android:ems="10"
        android:textColorHint="#ffffff"
        android:textColor="#ffffff"
        android:id="@+id/editText"
        android:capitalize="none"
        android:hint="E-mail"
        android:singleLine="true"
        android:layout_marginTop="30dp"
        android:layout_gravity="center"
        android:paddingLeft="15dp"
         />

    <EditText
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:textColor="#ffffff"
        android:inputType="textPassword"
        android:ems="10"
        android:id="@+id/editText2"
        android:hint="Password"
        android:fontFamily=""
        android:layout_marginTop="5dp"
        android:layout_gravity="center"
        android:textColorHint="#ffffff"
        android:paddingLeft="15dp"/>


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/sign_in"
        android:text="@string/sign_in"
        android:textColor="#ffffff"
        android:background="@drawable/button_signin4"
        android:layout_gravity="center"
        android:layout_marginTop="25dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#ffffff"
        android:paddingLeft="35dp"
        android:id="@+id/sign_in_fd"
        android:background="@drawable/button_fblogin_small2"
        android:text="@string/logfb"
        android:textSize="13dp"
        android:layout_gravity="center"
        android:layout_marginTop="35dp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/sign_in_fb"
        android:background="@drawable/button_glogin_small"
        android:text="@string/logg"
        android:textColor="#ffffff"
        android:paddingLeft="35dp"
        android:layout_gravity="center"
        android:layout_marginTop="10dp"/>

   <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="bottom"
    >




    <Button
        android:id="@+id/pwrecovery"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/lost_password"
        android:textColor="#ffffff"
        android:gravity="left"
        android:textSize="18dp"
        android:clickable="true"/>


    <TextView
        android:id="@+id/signup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/sign_up"
        android:textColor="#ffffff"
        android:gravity="right"
        android:textSize="18dp"
        android:clickable="true"/>
   </RelativeLayout>




     </LinearLayout>

Click here for Plunker

3 个答案:

答案 0 :(得分:2)

利用Template references #click1#click2,以便您可以控制您的组件。

    <div>
      <click-me #click1></click-me>
      <input type="input" value="friend 2 to hide" id="clickme1" [hidden] = "click1.type">
    </div>

    <div>
      <click-me #click2></click-me>
      <input type="input" value="friend 2 to hide" id="clickme2" [hidden] = "click2.type">
    </div>

答案 1 :(得分:2)

使用Translusion

Demonstration

我认为制作此组件的最佳方法是在重复组件中转换您想要的任何内容。

然后在复制组件内部,您可以将transcluded内容存储在span标记内,以便保留样式。然后添加一个单击处理程序,用于切换span标记的隐藏。

请注意,您不仅可以将输入元素用于其他组件,还可以将其包装在重复组件中。

// app.component.html

// app.component.html
<click-me>
  <input type="input" value="friend 1 to hide" id="clickme2">
</click-me>

<click-me>
  <input type="input" value="friend 2 to hide" id="clickme2">
</click-me>

<click-me>
  <input type="input" value="friend 3 to hide" id="clickme2">
</click-me>

// duplicate.component.ts
import {Component} from 'angular2/core';

@Component({
    selector: 'click-me',
    template: `
      <button (click)="onClickMe()">Hide A Friend Input</button>
      <span [hidden]="hidden">
        <ng-content></ng-content>
      </span>
    `
})

export class DuplicateComponent {
    hidden = false;

    onClickMe() {
        this.hidden = !this.hidden;
    }
}

答案 2 :(得分:0)

我会做的是

  1. DuplicateComponent组件
  2. 中定义输出事件
  3. onClickMe()方法
  4. 中触发输出事件
  5. 通过模板变量定义每个出现的特定名称 ContainerComponent模板中的DuplicateComponent(即 包含DuplicateComponent
  6. 实例的组件
  7. 在每次出现时收听新创建的事件 DuplicateComponent使用传递特定方法的方法 已触发事件的DuplicateComponent实例
  8. 执行DuplicateComponent实例所需的操作 附加为新创建事件的侦听器的方法
  9. 这可能听起来很复杂,但我认为代码很简单(参见working plunkr

    <强> DuplicateComponent

    import {Component, Output, EventEmitter} from 'angular2/core';
    @Component({
        selector: 'click-me',
        template: `<button (click)="onClickMe()">Hide A Friend Input</button>`
    })
    export class DuplicateComponent {
      @Output() haveBeenClicked = new EventEmitter<any>();
        onClickMe() {
            this.haveBeenClicked.next();
            this.type = "hidden";
        }
    }
    

    AppComponent模板                        

    <div>
      <click-me (haveBeenClicked)="doStuff(two)"></click-me>
      <input type="input" value="friend 2 to hide" id="clickme2" #two>
    </div>
    

    <强> AppComponent

    @Component({
        selector: 'my-app',
        templateUrl: 'app/app.component.html',
        directives: [DuplicateComponent]
    })
    export class AppComponent {
      constructor AppComponent {}
    
      doStuff(inputElement) {
        console.log(inputElement);
      }
    }