首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角2+开发框架组件

角2+开发框架组件
EN

Stack Overflow用户
提问于 2017-12-08 05:51:07
回答 2查看 69关注 0票数 1

我正试图为企业网站开发一些基本的框架控件,开发人员可以指定某些原语类型,这些基本类型可以用最少的工作来实现一致性,但仍然有能力完全控制布局和内容。每个控件都负责定义样式和维护某些可访问性要求。在windows桌面应用程序中会有类似的情况。我可以将GroupBox或Panel拖到窗体上,并从表单中设置属性,但之后我可以向该面板添加控件和自定义内容,而无需了解要放置的内容。

因此,作为一个例子,到目前为止,我有一个仪表板组件,我想在屏幕顶部放置一些瓷砖,然后再放置几个面板。一个面板将显示一个表格,另一个面板将有一段文本,后面跟着一个图表,另一个面板将显示一些垂直堆叠的瓷砖。我需要指定框架控件以及放置它的位置,但我不确定如何传递富内容或要在面板组件的panel-body div中呈现的另一个配置组件。

仪表板模板定义了一个瓷砖,后面跟着一些接受属性的面板,这些属性很容易绑定,因为这些是已知的字符串值:

代码语言:javascript
复制
<h1 class="page-header">{{title}}</h1>
<div class="row">
    <div class="col-md-3 col-sm-6">
      <app-infra-tile headerText="Total Visitors" [mainText]="'0' | number" footerText="Some Text" icon="fa-users" colour="bg-blue"></app-infra-tile>
    </div>

</div>
<div class="row">
  <div class="col-md-3 col-sm-6">
    <app-infra-panel heading="Table Panel"></app-infra-panel>
  </div>
  <div class="col-md-3 col-sm-6">
    <app-infra-panel heading="Graph Panel"></app-infra-panel>
  </div>
  <div class="col-md-3 col-sm-6">
    <app-infra-panel heading="Some Panel"></app-infra-panel>
  </div>
</div>

Tile组件与模板

代码语言:javascript
复制
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-infra-tile',
  templateUrl: './tile.component.html',
  styleUrls: ['./tile.component.css']
})
export class TileComponent implements OnInit {
  @Input() icon: string;
  @Input() headerText: string;
  @Input() mainText: string;
  @Input() footerText: string;
  @Input() colour = 'bg-blue';

  constructor() { }

  ngOnInit() {
  }

}
<div class="widget widget-stats {{colour}}">
  <div *ngIf="icon" class="stats-icon"><i class="fa {{icon}}"></i></div>
  <div class="stats-info">
      <div class="stats-title | uppercase">{{headerText}}</div>
      <div class="stats-number">{{mainText}}</div>  
      <div class="stats-desc">{{footerText}}</div>
  </div>
</div>

面板组件和模板

代码语言:javascript
复制
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-infra-panel',
  templateUrl: './panel.component.html',
  styleUrls: ['./panel.component.css']
})
export class PanelComponent implements OnInit {
  @Input() htmlId: string;
  @Input() heading: string;

  constructor() { }

  ngOnInit() {
  }

}
<div class="panel panel-inverse" id="{{htmlId}}">
  <div class="panel-heading">
    <div class="panel-heading-btn">
        <a href="javascript:;" class="btn btn-xs btn-icon btn-circle btn-default" data-click="panel-expand"><i class="fa fa-expand"></i></a>
        <a href="javascript:;" class="btn btn-xs btn-icon btn-circle btn-success" data-click="panel-reload"><i class="fa fa-repeat"></i></a>
        <a href="javascript:;" class="btn btn-xs btn-icon btn-circle btn-warning" data-click="panel-collapse"><i class="fa fa-minus"></i></a>
        <a href="javascript:;" class="btn btn-xs btn-icon btn-circle btn-danger" data-click="panel-remove"><i class="fa fa-times"></i></a>
    </div>
    <h4 class="panel-title">{{heading}}</h4>
  </div>
  <div class="panel-body">
    -----  The internal content managed by the dashboard should be rendered here  ----
  </div>
</div>

我考虑过传递一个包含工厂方法的服务,并在面板中将any类型的局部变量设置为结果,但是如果仪表板只是实现该方法以输出原始html,还是可以通过.??

任何建议都是非常感谢的。我可能错过了一些很简单的东西。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-14 05:26:50

我认为移除 (NG2+中的内容投影)是可行的

票数 0
EN

Stack Overflow用户

发布于 2017-12-13 21:08:22

一周内几乎看不见,但这是同事给出的答案。方法是使用指令。因此,如果我有一个仪表板组件,我将放置几个面板,而不必反复编写Panel html,我会在DashboardComponent的模板中这样做:

代码语言:javascript
复制
<div class="row">
  <div class="col-md-4 col-sm-6">
    <app-infra-panel heading="Some Panel" [componentName]="somePanelComponent"></app-infra-panel>
  </div>

  <div class="col-md-8 col-sm-6">
    <app-infra-panel heading="Other Panel" [componentName]="otherPanelComponent"></app-infra-panel>
  </div>
</div>

heading是PanelComponent以及somePanelComponentotherPanelComponent的一个属性。对于我打算用一些Sub Component填充的每个面板,我都会为组件名称创建一个对应的字符串。

代码语言:javascript
复制
@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class ProviderDashboardComponent implements OnInit {
  title = 'The Dashboard';

  // Panel Content Component Names
  somePanelComponent = 'SomePanelComponent';
  otherPanelComponent = 'OtherPanelComponent';


  constructor() { }

  ngOnInit() {    

  }

}

正在放置的PanelComponent:

代码语言:javascript
复制
<div class="panel panel-inverse">
  <div class="panel-heading">
    <div class="panel-heading-btn">
        <a href="javascript:;" class="btn btn-xs btn-icon btn-circle btn-default" data-click="panel-expand"><i class="fa fa-expand"></i></a>
        <a href="javascript:;" class="btn btn-xs btn-icon btn-circle btn-success" data-click="panel-reload"><i class="fa fa-repeat"></i></a>
        <a href="javascript:;" class="btn btn-xs btn-icon btn-circle btn-warning" data-click="panel-collapse"><i class="fa fa-minus"></i></a>
        <a href="javascript:;" class="btn btn-xs btn-icon btn-circle btn-danger" data-click="panel-remove"><i class="fa fa-times"></i></a>
    </div>
    <h4 class="panel-title">{{heading}}</h4>
  </div>
  <div class="panel-body">
    <div control-factory component="{{componentName}}"></div>
  </div>
</div>

import { Component, Input, ComponentFactoryResolver, ViewChild } from '@angular/core';

@Component({
  selector: 'app-infra-panel',
  templateUrl: './panel.component.html',
  styleUrls: ['./panel.component.css']
})
export class PanelComponent {

  @Input() heading: string;
  @Input() componentName: string;

  constructor() { }

}

control-factory指令:

代码语言:javascript
复制
import {  Directive,
  Component,
  ComponentFactory,
  OnChanges,
  Input,
  ViewContainerRef,
  Compiler,
  ComponentFactoryResolver,
  OnDestroy
} from '@angular/core';

import { CommonModule } from '@angular/common';
import { AppComponent } from 'app/app.component';

@Directive({
  selector: '[control-factory]'
})
export class ControlFactoryDirective implements OnChanges, OnDestroy {

  @Input() component: string;
  componentRef: any;
  init = false;
  factoryClass: any;

  constructor(private vcRef: ViewContainerRef, private resolver: ComponentFactoryResolver) { }

  ngOnChanges(): void {

    if (!this.component || this.init) return;

    var factories = Array.from(this.resolver['_factories'].keys());
    console.log(this.component);

    this.factoryClass = factories.find((x: any) => x.name === this.component);
    const factory = this.resolver.resolveComponentFactory<any>(this.factoryClass);
    const compRef = this.vcRef.createComponent(factory);


    if (this.componentRef) {
      this.componentRef.destroy();
    }

    this.componentRef = compRef;
    this.init = true;
  }

  public ngOnDestroy() {
    if (this.componentRef) {
      this.componentRef.destroy();
      this.componentRef = null;
    }
  }
}

对于放置在面板中的每个组件,都需要创建一个组件,在我的示例中是SomePanelComponentOtherPanelComponent。这些也需要添加到declarationsentryComponents数组中的App.module中。我正在努力研究如何在我的项目中把这些模块放在更深的模块中,而不是把所有的东西都放在顶层。到目前为止,无论我把它们放在哪里,我都会收到错误,如果它们不在entryComponents数组中,则在App.module数组中没有指定它们。

不管怎么说,我希望这对任何人都有价值。

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

https://stackoverflow.com/questions/47708479

复制
相关文章

相似问题

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