4

我对 Angular 比较陌生,我正在努力使用一个通用模块为多个页面创建相同的行为。

情况如下:我正在创建一个带有多个“页面”的CRUD SPA(使用路由)。事实证明,其中几个页面具有相同的结构和行为,并且仅(在视觉上)与项目在列表中的呈现方式及其选择时的详细信息不同。像Asana的几个页面一样思考,页面之间的唯一区别是列表和详细信息呈现器的方式。

我正在考虑为这些页面中的每一个创建一个模块,但复制和粘贴所有代码只是为了更改一小部分文件似乎很糟糕(更新也将是一场噩梦)。

我想要实现的解决方案是创建一个主 CRUD 模块,其中包含一个 Component/html/css,我可以在其中以某种方式参数化每个页面要使用的渲染器。或任何其他具有尽可能少的复制粘贴的解决方案。

谢谢您的帮助。

4

2 回答 2

1

我阅读了该工具和其他一些东西,比如动态创建的组件,但没有一个是我想要的(特别是考虑到学习曲线)。所以,我花了一些时间,但我自己找到了一个(非常疯狂的)解决方案。

首先,我创建了一个基本模块。在其中,我创建了一个PageComponent调用我需要的页面的两个部分:一个用于列表,另一个用于详细信息(如 Asana)。page.component.html模板如下所示:

<div class="mdl-grid">
    <div class="mdl-cell mdl-cell--8-col">
        <app-list></app-list>
    </div>
    <div class="mdl-cell mdl-cell--4-col">
        <app-details></app-details>
    </div>
</div>`

在这个基础模块中,我为我需要的每个组件(anAbstractListComponentAbstractDetailsComponent)创建了一个抽象基类。我在使用构造函数中的访问字进行依赖注入和自动变量创建时遇到了一些问题,所以我的解决方案如下:

export abstract class AbstractDetailsComponent {
    protected service: BaseService;

    protected constructor(service: BaseService) {
        this.service = service;
    }
}

请注意,我没有使用@Component装饰器,因为它会被忽略(PageComponent也)。另一件事是Base*创建了一些类和接口以确保一致性(如BaseService)。

如您所见,当PageComponent请求<app-list>和时,没有人会回答<app-details>。这里开始疯狂的部分。

对于每个页面,我都创建了一个模块,并在其中创建了填补空白的组件。此外,页面的主要组件扩展了PageComponent. 例如,在我的应用程序中,我有一个技能页面,它会导致以下内容SkillsComponent

@Component({
    selector: 'skills-page', // doesn't really matter, this will be called by the router
    templateUrl: '../base-module/page.component.html',
    styleUrls: [ '../base-module/page.component.css', './skills.component.css' ]
})
export class SkillsComponent extends PageComponent { }

请注意,templateUrl其中一个样式指向基本模块内的文件。这是我发现在所有页面之间共享相同页面结构的方式。

现在,差距。我需要的两个组件都是相似的。基本上,我为每一个扩展基类并注入正确的服务。这是SkillDetailsComponent

@Component({
    selector: 'app-details', // <-- the name required by the PageComponent template
    templateUrl: './skill-details.component.html',
    styleUrls: [ '../base-module/details.component.css', './skills-details.component.css' ]
})
export class SkillsDetailsComponent extends DetailsComponent {
    public constructor(service: SkillsService) {
        super(service);
    }
}

selector正是 所要求的page.component.html。所有页面的所有列表和详细信息组件共享相同的方法。这使得相同的模板在所有页面中都很有用,因为选择器是相同的。

另一件事是构造函数。我必须这样做才能注入正确的服务。

最终的文件结构如下所示:

app/
    ├ base-module/
    │    ├ base.component.css
    │    ├ base.component.html
    │    ├ base.component.ts
    │    ├ base.module.ts
    │    ├ details.component.css
    │    ├ details.component.ts
    │    ├ list.component.css
    │    ├ list.component.html
    │    └ list.component.ts
    └ skills-module/
        ├ skills-details.component.css
        ├ skills-details.component.ts
        ├ skills-list.component.css
        ├ skills-list.component.ts
        ├ skills.component.css
        ├ skills.component.html
        ├ skills.component.ts
        └ skills.module.ts

我不知道这是否是最好的解决方案,但它就像我需要的那样醒来。解释我所做的所有步骤有点困难(通常这是一个过于复杂的解决方案的标志),但我希望它是可以理解的。

于 2017-05-25T03:56:29.790 回答
0

我的猜测是您正在使用ng-route. 尝试查看ui-router https://github.com/angular-ui/ui-router

UI-Router 是事实上的标准 AngularJS 客户端路由框架,支持嵌套视图。UI-Router 背后的概念是将视图建模为状态的分层树。

于 2017-05-12T20:01:38.827 回答