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