Angular 如何在父指令中获取子项的模型?

Angular 如何在父指令中获取子项的模型?,angular,Angular,我已经创建了一个指令并将其分配给一个元素,它的子元素是ngModel的输入,我想从父指令重置子ngModel 我已经试过了 HTML:- 有没有其他方法,不用@Input。因为这样我必须创建本地模板变量并将其分配给@Input。尝试创建一个名为childModelChange()的Output属性。然后Angular将自动更新父属性。然后,每当子级更改值时,我们需要emit()一个事件: 您可以设置从子级到父级的事件发射器通信(输出)。例如: 从'angular2/core'导入{Compon

我已经创建了一个指令并将其分配给一个元素,它的子元素是ngModel的输入,我想从父指令重置子ngModel

我已经试过了

HTML:-



有没有其他方法,不用@Input。因为这样我必须创建本地模板变量并将其分配给@Input。

尝试创建一个名为
childModelChange()
Output
属性。然后Angular将自动更新父属性。然后,每当子级更改值时,我们需要
emit()
一个事件:

您可以设置从子级到父级的事件发射器通信(输出)。例如:

从'angular2/core'导入{Component,EventEmitter,Input,Output}

@Component({
    selector: 'yourChild',
    template: `
        <p>yourChild yourSharedVariable: {{yourSharedVariable}}</p>
        <input [ngModel]="yourSharedVariable" (ngModelChange)="change($event)">
    `
})
export class yourChildComponent {
    @Input() yourSharedVariable: string;
    @Output() yourSharedVariableChange = new EventEmitter();
    change(newValue) {
      console.log('newvalue', newValue)
      this.yourSharedVariable = newValue;
      this.yourSharedVariableChange.emit(newValue);
    }
}
@组件({
选择器:“您的孩子”,
模板:`
您的孩子yourSharedVariable:{{yourSharedVariable}

` }) 导出类组件{ @Input()yourSharedVariable:string; @Output()yourSharedVariableChange=neweventemitter(); 更改(新值){ console.log('newvalue',newvalue) this.yourSharedVariable=newValue; this.yourSharedVariableChange.emit(newValue); } }
您的父组件:

@Component({
    selector: 'parent',
    template: `
        <div>Parent yourSharedVariableParent: {{yourSharedVariableParent}}</div>
        <yourChild [(yourSharedVariable)]="yourSharedVariableParent"></yourChild>
    `,
    directives: [yourChildComponent]
})
export class ParentComponent {
    yourSharedVariableParent ='hello';
    constructor() { console.clear(); }
}
@组件({
选择器:'父',
模板:`
父级yourSharedVariableParent:{{yourSharedVariableParent}}
`,
指令:[yourChildComponent]
})
导出类ParentComponent{
yourSharedVariableParent='hello';
构造函数(){console.clear();}
}

尝试创建名为
childModelChange()
输出
属性。然后Angular将自动更新父属性。然后,每当子级更改值时,我们需要
emit()
一个事件:

您可以设置从子级到父级的事件发射器通信(输出)。例如:

从'angular2/core'导入{Component,EventEmitter,Input,Output}

@Component({
    selector: 'yourChild',
    template: `
        <p>yourChild yourSharedVariable: {{yourSharedVariable}}</p>
        <input [ngModel]="yourSharedVariable" (ngModelChange)="change($event)">
    `
})
export class yourChildComponent {
    @Input() yourSharedVariable: string;
    @Output() yourSharedVariableChange = new EventEmitter();
    change(newValue) {
      console.log('newvalue', newValue)
      this.yourSharedVariable = newValue;
      this.yourSharedVariableChange.emit(newValue);
    }
}
@组件({
选择器:“您的孩子”,
模板:`
您的孩子yourSharedVariable:{{yourSharedVariable}

` }) 导出类组件{ @Input()yourSharedVariable:string; @Output()yourSharedVariableChange=neweventemitter(); 更改(新值){ console.log('newvalue',newvalue) this.yourSharedVariable=newValue; this.yourSharedVariableChange.emit(newValue); } }
您的父组件:

@Component({
    selector: 'parent',
    template: `
        <div>Parent yourSharedVariableParent: {{yourSharedVariableParent}}</div>
        <yourChild [(yourSharedVariable)]="yourSharedVariableParent"></yourChild>
    `,
    directives: [yourChildComponent]
})
export class ParentComponent {
    yourSharedVariableParent ='hello';
    constructor() { console.clear(); }
}
@组件({
选择器:'父',
模板:`
父级yourSharedVariableParent:{{yourSharedVariableParent}}
`,
指令:[yourChildComponent]
})
导出类ParentComponent{
yourSharedVariableParent='hello';
构造函数(){console.clear();}
}

您可以使用ContentChild或ContentChildren。当您想要查找NgModel时,您的指令变成

  @ContentChild(NgControl, { static: true }) input

  someFunc() {
    this.input.control.setValue(null);
  }
(NgControl)是使用[ngModel]或[formControl]或formControlName(如果我们使用的是ReactiveForm)的任何输入

我们可以有一个app.component,比如

<div  hello >
  <input [ngModel]="value"/>
</div>
<button (click)="do()">clear</button>

export class AppComponent  {
  @ViewChild(HelloDirective,{static:true}) wrapper
  do()
  {
    this.wrapper.someFunc()
  }
}
指令变为(见注释以获取简要说明)


您可以使用ContentChild或ContentChildren。当您想要查找NgModel时,您的指令变成

  @ContentChild(NgControl, { static: true }) input

  someFunc() {
    this.input.control.setValue(null);
  }
(NgControl)是使用[ngModel]或[formControl]或formControlName(如果我们使用的是ReactiveForm)的任何输入

我们可以有一个app.component,比如

<div  hello >
  <input [ngModel]="value"/>
</div>
<button (click)="do()">clear</button>

export class AppComponent  {
  @ViewChild(HelloDirective,{static:true}) wrapper
  do()
  {
    this.wrapper.someFunc()
  }
}
指令变为(见注释以获取简要说明)


谢谢大家的回复

这可以使用
@ContentChildren
,因为
@ContentChildren
总是给出第一个/父ngModel,但我需要一个特定的ngModel,所以我使用了
@ContentChildren

目前在我的例子中,只有一个孩子,所以目前我访问this.input.last.control.setValue(null) 如果有多个ngModel,如何从中获得特定的ngModel

顺便说一下,我已经创建了一个材料选择搜索,在打开时我聚焦输入字段(搜索框),在关闭时清除其模型


注意:我不想创建组件,因为这会增加大量代码和逻辑

谢谢大家的回复

这可以使用
@ContentChildren
,因为
@ContentChildren
总是给出第一个/父ngModel,但我需要一个特定的ngModel,所以我使用了
@ContentChildren

目前在我的例子中,只有一个孩子,所以目前我访问this.input.last.control.setValue(null) 如果有多个ngModel,如何从中获得特定的ngModel

顺便说一下,我已经创建了一个材料选择搜索,在打开时我聚焦输入字段(搜索框),在关闭时清除其模型


注意:我不想创建组件,因为这会增加大量代码和逻辑

我建议您看看:在这种情况下,创建组件而不是属性并使用ViewChild访问父元素的内容不是很好吗?我建议您看看:在这种情况下,创建组件而不是属性并使用ViewChild访问父元素的内容不是很好吗@Sammer Khan,我更新了我的答案,我不知道这是否有帮助you@Eliseo,我想我没有把我的问题解释清楚,很抱歉。我正在用搜索创建选择[类似的东西]()一旦关闭选择输入,它将清除搜索关键字,而不是添加按钮新的更新:)@Sammer Khan,我更新了我的答案,我不知道这是否有帮助you@Eliseo,我想我没有把我的问题解释清楚,很抱歉。我正在使用搜索创建选择[类似于此]()一旦关闭选择输入,它将清除搜索关键字,而不是使用添加按钮一个新的更新:)
@Directive({
  selector: '[clear]',
  host: {  //we need an "extra" space to the rigth
    '[style.margin-right]': '"1.5rem"',
  }
})
export class ClearDirective implements OnInit {

  div: any;
  @ContentChild(NgControl) control; //we get the "input"

  @HostListener('click', ['$event']) click($event) {
    //we add a HostListener "click" and take account is we click
    //in the "cross" we created, is a span with class="close"
    if ($event.target.getAttribute('class') == 'close') {
      this.control.control.setValue(null);  //remember, the control is the NgControl
      $event.stopPropagation();
    }
  }
  constructor(private renderer: Renderer2, private el: ElementRef) { }
  ngOnInit() {
    //we need take account about when the value of the control is "something"
    //or none
    if (this.control)
      this.control.valueChanges.subscribe((value) => {
        if (!value) {  //if no value
          this.clearCross()  //remove the cross
        }
        else {
          if (!this.div) {  //if not yet the cross
            this.createCross()  //create
          }
        }
      })

  }
  createCross() {
    //we wan create some like
    /*
       <div class="mat-form-field-suffix">
         <span class="close"></span>
       </div>
    */
    this.div = this.renderer.createElement('div');
    this.renderer.addClass(this.div, "mat-form-field-suffix")

    const span = this.renderer.createElement('span')
    this.renderer.addClass(span, "close")

    this.renderer.appendChild(this.div, span);
    this.renderer.appendChild(this.el.nativeElement, this.div);
  }
  clearCross() {
    if (this.div)  //simply remove the "cross"
    {
      this.renderer.removeChild(this.el.nativeElement, this.div)
      this.div=null
    }
  }
<mat-form-field clear>
  <input matInput type="text" placeholder="Clearable input" [(ngModel)]="value">
</mat-form-field>
export class ClearDirective implements OnInit {

  div: any;
  constructor(@Optional() private control:NgControl,private renderer: Renderer2, private el: ElementRef) { }
  ngOnInit() {
    if (this.control)
      this.control.valueChanges.subscribe((value) => {
        if (!value) {
          this.clearCross()
        }
        else {
          if (!this.div) {
            this.createCross()
          }
        }
      })

  }
  createCross() {
    this.div = this.renderer.createElement('div');
    this.renderer.addClass(this.div, "wrapper")

    const span = this.renderer.createElement('span')
    this.renderer.addClass(span, "close")

    this.renderer.appendChild(this.div, span);
    this.renderer.insertBefore(this.renderer.parentNode(this.el.nativeElement),this.div,this.el.nativeElement,);
    this.renderer.listen(this.div, 'click', ($event) => {
           this.control.control.setValue(null);
           $event.stopPropagation();
       });
  }
  clearCross() {
    if (this.div)
    {
      this.renderer.removeChild(this.renderer.parentNode(this.el.nativeElement), this.div)
      this.div=null
    }
  }
}
@ContentChildren(NgControl) input;
this.input.last.control.setValue(null);