首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有各种列表项目模板的通用列表

有各种列表项目模板的通用列表
EN

Stack Overflow用户
提问于 2017-07-05 11:11:09
回答 1查看 2.6K关注 0票数 2

我正在尝试建立一个通用组件,它显示一个具有角度4和材料设计的项目列表。我们的目标是,有一个列表,其中我只提供这样的子组件:

代码语言:javascript
复制
<generic-list 
  title="My name list title"
  [items]="names" 
  (change)="handleNameChanged($event)">
    <some-child let-item="name"></some-child>
</generic-list>

@ViewChild(GenericListItem)
childItem: GenericListItem;

或者这个:

代码语言:javascript
复制
<generic-list ... [type]="simpleListItem"></generic-list>

@Input() type: Type<GenericListItem>;

export class GenericListItem {
  @Input() value: any;
}

因此,任何子组件都应该从GenericListItem扩展而来,并且能够按自己的意愿显示value的属性。一些我需要的示例组件:

代码语言:javascript
复制
@Component({
  selector: 'app-simple-list-item',
  template: '<p>{{value?.name}}</p>'
})
export class SimpleListItem extends GenericListItem {
}

@Component({
  selector: 'app-chechbox-list-item',
  template: '<md-checkbox [(ngModel)]="value?.enabled">{{value?.name}} &
    {{value?.email}}</md-checkbox>'
})
export class CheckboxListItem extends GenericListItem {
}

generic-list组件如下所示:

代码语言:javascript
复制
<md-list>
  <h2 md-subheader>{{title}}</h2>
  <md-list-item #outlet
    *ngFor="let item of items; let i = index"
    (click)="change.emit(item)">
    // in here should go the content for each item
  </md-list-item>
</md-list>

我一直在寻找实现这一目标的方法,但是,目前已经存在的解决方案中没有一种是有效的,或者是不受欢迎的。另外,关于这个主题的一些多余的文档也没有帮助.

我找到了我试图修改的this帖子,从而在generic-list中生成了这段代码

代码语言:javascript
复制
export class GenericListComponent implements OnInit, AfterViewInit {
//inputs, outputs and other properties here
@ViewChildren('outlet', {read: ViewContainerRef})
outlets: QueryList<ViewContainerRef>;

ngOnInit() {
}

ngAfterViewInit() {
  console.log(this.outlets); // prints '3', since I've declared 3 items
  this.isViewInitialized = true;
  this.updateChildren();
}

updateChildren() {
  if (!this.isViewInitialized) {
    return;
  }
  this.outlets.forEach((outlet, index) => {
    const factory = this.cfr.resolveComponentFactory(this.type);
    const componentRef = outlet.createComponent(factory);
    componentRef.instance.value = this.items[index];
  });
}

,这将导致有关ChangeDetection的错误

错误: ExpressionChangedAfterItHasBeenCheckedError:表达式检查后发生了更改。以前的值:“未定义”。现值:“Hi1V”。该视图似乎是在其父视图和其子视图被脏检查后创建的。它是否是在更改检测挂钩中创建的?

我的测试组件:

代码语言:javascript
复制
<app-generic-list
  title="AppTitle"
  [items]="names"
  [type]="simpleListItem"
  (change)="handleItemChanged($event)"></app-generic-list>

export class AppComponent {
  simpleListItem = SimpleListItemComponent;
  names = [
    {value: 'Hi1V', desc: 'Hello1'},
    {value: 'Hi2V', desc: 'Hello2'},
    {value: 'Hi3V', desc: 'Hello3'}
  ];

  handleItemChanged(item: string) {
    console.log(item);
  }
}

看起来我可能已经接近解决方案了,但是现在我不知道在什么时候需要实例化组件。另外,子组件中的自定义输出是否工作,并且可以从generic-list外部调用?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-01 19:52:09

https://github.com/elgervb/ngx-components/blob/master/src/app/list/list.component.ts不是更好的解决方案吗?您可以创建一个列表并提供一个模板来呈现项目。在模板中,可以使用自己的自定义组件。

都是以一种非常通用的方式。

使用的一个例子是:

代码语言:javascript
复制
<evb-list [items]="items" [filterEnabled]="true">

<ng-template let-item>
  <md-checkbox [(ngModel)]="item?.enabled">{{item?.name}} &&
  {{value?.email}}</md-checkbox>
</ng-template>

其中ng-模板中的项将是列表中的每个项。

我认为这个组件以一种通用的方式实现了您想要的一切。

希望这能帮上忙

;-)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44924639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档