Javascript 嵌套在同一组件事件发射器内的角度8组件
我使用了嵌套在同一组件中的组件。当我在正确调用的父组件附加函数中更改复选框时,事件发射器工作正常,但当我更改子复选框时,附加函数被激发,但事件发射器不可用(据我所知,问题不是与子组件绑定)。我想在更改子对象中的复选框时发出数据 如果有人知道答案,请帮我解决这个问题。使用嵌套在同一组件中的组件的术语是什么 谢谢你 这是stackblitz链接 (请检查控制台) tree.component.tsJavascript 嵌套在同一组件事件发射器内的角度8组件,javascript,angular,typescript,ionic-framework,angular8,Javascript,Angular,Typescript,Ionic Framework,Angular8,我使用了嵌套在同一组件中的组件。当我在正确调用的父组件附加函数中更改复选框时,事件发射器工作正常,但当我更改子复选框时,附加函数被激发,但事件发射器不可用(据我所知,问题不是与子组件绑定)。我想在更改子对象中的复选框时发出数据 如果有人知道答案,请帮我解决这个问题。使用嵌套在同一组件中的组件的术语是什么 谢谢你 这是stackblitz链接 (请检查控制台) tree.component.ts import { Component, OnInit, Input, Output, EventEmi
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-tree',
templateUrl: './tree.component.html',
styleUrls: ['./tree.component.css'],
})
export class TreeComponent {
@Input() treeData: any;
@Output() toggleEmitter: EventEmitter<any> = new EventEmitter();
constructor() {}
toggleChild(node) {
console.log('from tree start');
console.log(node);
console.log('from tree end');
this.toggleEmitter.emit(node);
// if ('children' in node && node.children.length) {
// node.isExpand = !node.isExpand;
// }
}
test(node, i) {
node.parentIndex = i;
console.log(node);
// this.toggleEmitter.emit(node);
}
CBchangeEvent(node) {
console.log(node);
this.toggleEmitter.emit(node);
}
}
ul {
list-style-type: none !important;
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TreeComponent } from './tree.component';
import {
MatIconModule, MatCheckboxModule, MatFormFieldModule, MatButtonModule
} from '@angular/material';
@NgModule({
imports: [
CommonModule,
MatIconModule,
MatCheckboxModule,
MatFormFieldModule,
MatButtonModule
],
declarations: [TreeComponent],
exports: [TreeComponent]
})
export class TreeModule {
static forRoot() {
return {
ngModule: TreeModule
}
}
}
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
myData = [
{'id':1, 'name':'Main 1','isExpand':false,
'children':[
{'id':1, 'name':'Child 1', 'isExpand':false,
'children':[
{'id':2, 'name':'Test2','isExpand':false}
]
}
]
},
{
'id':2, 'name':'Main 2','isExpand':false
}
]
test(node) {
console.log('from app start');
console.log(node);
console.log('from app end');
if ('children' in node && node.children.length) {
node.isExpand = !node.isExpand;
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TreeModule } from './tree/tree.module';
import {
MdToolbarModule,
MdTabsModule,
MdButtonModule,
MdInputModule,
MdDatepickerModule,
MdNativeDateModule,
MdCheckboxModule,
MdRadioModule,
NoConflictStyleCompatibilityMode
} from '@angular/material';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule, BrowserAnimationsModule, MdToolbarModule, MdTabsModule, MdButtonModule, MdInputModule, MdDatepickerModule, MdNativeDateModule, MdCheckboxModule, MdRadioModule, TreeModule, NoConflictStyleCompatibilityMode ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
tree.module.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-tree',
templateUrl: './tree.component.html',
styleUrls: ['./tree.component.css'],
})
export class TreeComponent {
@Input() treeData: any;
@Output() toggleEmitter: EventEmitter<any> = new EventEmitter();
constructor() {}
toggleChild(node) {
console.log('from tree start');
console.log(node);
console.log('from tree end');
this.toggleEmitter.emit(node);
// if ('children' in node && node.children.length) {
// node.isExpand = !node.isExpand;
// }
}
test(node, i) {
node.parentIndex = i;
console.log(node);
// this.toggleEmitter.emit(node);
}
CBchangeEvent(node) {
console.log(node);
this.toggleEmitter.emit(node);
}
}
ul {
list-style-type: none !important;
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TreeComponent } from './tree.component';
import {
MatIconModule, MatCheckboxModule, MatFormFieldModule, MatButtonModule
} from '@angular/material';
@NgModule({
imports: [
CommonModule,
MatIconModule,
MatCheckboxModule,
MatFormFieldModule,
MatButtonModule
],
declarations: [TreeComponent],
exports: [TreeComponent]
})
export class TreeModule {
static forRoot() {
return {
ngModule: TreeModule
}
}
}
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
myData = [
{'id':1, 'name':'Main 1','isExpand':false,
'children':[
{'id':1, 'name':'Child 1', 'isExpand':false,
'children':[
{'id':2, 'name':'Test2','isExpand':false}
]
}
]
},
{
'id':2, 'name':'Main 2','isExpand':false
}
]
test(node) {
console.log('from app start');
console.log(node);
console.log('from app end');
if ('children' in node && node.children.length) {
node.isExpand = !node.isExpand;
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TreeModule } from './tree/tree.module';
import {
MdToolbarModule,
MdTabsModule,
MdButtonModule,
MdInputModule,
MdDatepickerModule,
MdNativeDateModule,
MdCheckboxModule,
MdRadioModule,
NoConflictStyleCompatibilityMode
} from '@angular/material';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule, BrowserAnimationsModule, MdToolbarModule, MdTabsModule, MdButtonModule, MdInputModule, MdDatepickerModule, MdNativeDateModule, MdCheckboxModule, MdRadioModule, TreeModule, NoConflictStyleCompatibilityMode ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
应用程序组件.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-tree',
templateUrl: './tree.component.html',
styleUrls: ['./tree.component.css'],
})
export class TreeComponent {
@Input() treeData: any;
@Output() toggleEmitter: EventEmitter<any> = new EventEmitter();
constructor() {}
toggleChild(node) {
console.log('from tree start');
console.log(node);
console.log('from tree end');
this.toggleEmitter.emit(node);
// if ('children' in node && node.children.length) {
// node.isExpand = !node.isExpand;
// }
}
test(node, i) {
node.parentIndex = i;
console.log(node);
// this.toggleEmitter.emit(node);
}
CBchangeEvent(node) {
console.log(node);
this.toggleEmitter.emit(node);
}
}
ul {
list-style-type: none !important;
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TreeComponent } from './tree.component';
import {
MatIconModule, MatCheckboxModule, MatFormFieldModule, MatButtonModule
} from '@angular/material';
@NgModule({
imports: [
CommonModule,
MatIconModule,
MatCheckboxModule,
MatFormFieldModule,
MatButtonModule
],
declarations: [TreeComponent],
exports: [TreeComponent]
})
export class TreeModule {
static forRoot() {
return {
ngModule: TreeModule
}
}
}
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
myData = [
{'id':1, 'name':'Main 1','isExpand':false,
'children':[
{'id':1, 'name':'Child 1', 'isExpand':false,
'children':[
{'id':2, 'name':'Test2','isExpand':false}
]
}
]
},
{
'id':2, 'name':'Main 2','isExpand':false
}
]
test(node) {
console.log('from app start');
console.log(node);
console.log('from app end');
if ('children' in node && node.children.length) {
node.isExpand = !node.isExpand;
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TreeModule } from './tree/tree.module';
import {
MdToolbarModule,
MdTabsModule,
MdButtonModule,
MdInputModule,
MdDatepickerModule,
MdNativeDateModule,
MdCheckboxModule,
MdRadioModule,
NoConflictStyleCompatibilityMode
} from '@angular/material';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule, BrowserAnimationsModule, MdToolbarModule, MdTabsModule, MdButtonModule, MdInputModule, MdDatepickerModule, MdNativeDateModule, MdCheckboxModule, MdRadioModule, TreeModule, NoConflictStyleCompatibilityMode ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
app.component.html
<ul *ngIf="treeData">
<li *ngFor="let node of treeData;let i = index;">
<button mat-icon-button="" mattreenodetoggle="" class="mat-icon-button" (click)="toggleChild(node)">
<span class="mat-button-wrapper">
<mat-icon class="mat-icon material-icons" role="img" aria-hidden="true">
{{node.isExpand != 0 ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</span>
</button>
<mat-checkbox class="checklist-leaf-node" (change)="CBchangeEvent(node)">{{node.name}}</mat-checkbox>
<app-tree *ngIf="node.isExpand" [treeData]="node.children" (toggleEmitter)="test(node,i)"></app-tree>
</li>
</ul>
<app-tree [treeData]='myData' (toggleEmitter)="test($event)"></app-tree>
事件发射器就是这样工作的 父对象将数据传递给子对象 及 子级在通知父级数据已被删除时发出-以便 父级可以调用其回调函数 对于知道家长已更改日期的孩子 这里发生了数据绑定,就像*ngif的工作原理一样 当任何子项检查数据时,它将始终是最新的数据 子组件Input()变量将处于绑定时传递的变量的相同状态。绑定负责更新子UI-在绑定变量的状态发生变化时,您应该在子组件中绑定“toggleChild”,而不是绑定“test” 改变
<app-tree *ngIf="node.isExpand" [treeData]="node.children" (toggleEmitter)="test(node,i)"></app-tree>
到
这可能与:@BerkKurkcuoglu这与我的问题无关。谢谢@cfprabhu,您正在tree-component.html中使用应用程序树标记?tree-component.html标记再次附加到应用程序树组件。这不是我在做一个内循环循环吗?哦,我得到了它更像是递归构建树。嘿@cfprabhu你在下面的函数测试中注释掉了emit代码(node,I){node.parentIndex=I;console.log(node);//this.toggleEmitter.emit(node);}是的,兄弟。我知道工作的概念。如果你知道实现我目标的其他方法,请让我知道。没有兄弟。这是错误的。再读一遍我的问题,然后检查复选框对不起,我的错。所以,您想要的是,当切换子节点(例如数据中的“child1”)时,事件应该与其值一起发出?在child中,您将该方法与外部节点值绑定。(toggleEmitter)=“test(node,i)”不能在此处使用$event来获取子节点的值。类似于(toggleEmitter)=“test($event,i)”或test($event,node,i)?我在test this.toggleEmitter.emit(node);//第30行,并将值从(toggleEmitter)=“test(node,i)”更改为(toggleEmitter)=“test($event,i)”,并且能够一直获得子节点的值,直到应用程序组件。若您不希望事件以递归方式发出,那个么您可以保留该注释,并在测试中对子节点值执行任何您想执行的操作。