- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的问题有点简单。
假设我们有 2 个组件,每个组件都有自己的形式。
第一个组件:创建post.component.ts
第二部分:编辑-post.component.ts
当你创建 一个帖子,您只需填写该表单上的字段,如果一切都有效,您提交并创建该帖子(在某个内部数组中)。
当你编辑 一个帖子,您将特定的帖子对象加载到编辑组件中,然后编辑您需要的任何内容并提交。
现在,根据 单一职责 ,我们确实应该创建一个类来管理帖子创建和管理内部 UI 逻辑 该组件( edit-post.component.html )。
但是,我在许多示例中看到管理该案例的首选模式是使用 。 1 个表格 在编辑的情况下,他们只需保存 bool 值 当触发事件以通知特定监听器更改路由参数时设置。
如果该路由参数确实发生了更改,则有 If语句管理该特定逻辑(在 edit-form.component.ts 中实现的逻辑相同)。
让事件和监听器处理不同的目的似乎违反了单一责任。
这个例子很简单。在更高级的情况下,我们似乎可以非常快速地获得意大利面条代码。
如果我想坚持 Single 原则,实现这种情况的正确方法是什么?
最佳答案
我想就我认为非常有趣的这个问题添加我自己的想法。
Disclaimer: The code below doesn't tent to be a pure representation of SOLID in Angular but at least get close up to Single Responsability & Open-Close principles.I am totally open to any constructive comment and it would be great to have a look into another approaches.
single responsability
&
Open-close
不会过多影响我们的捆绑包大小的原则。
// user-form.component.ts
@Component({
selector: 'app-user-form',
template: `
<form [formGroup]="userForm" (submit)="submit.next($event)">
<label>Username</label>
<input type="text" formControlName="username" />
<label>Password</label>
<input type="password" formControlName="password" />
<!-- ... -->
<button type="submit" > Save </button>
</form>
`
})
export class UserFormComponent {
@Input() set user(user: User) {
this.userForm.patchValue({...user})
}
@Output() submit = new EventEmitter<User>();
userForm = new FormGroup({
username: new FormControl('', [Validators.Required, UserNameValidator]),
password: new FormControl('', [Validators.Required, PasswordValidator]
// ...
})
}
那么没关系被一个
edit-user-dialog.component.ts
包裹,
add-user.component.ts
等每个包装器可以以不同的方式管理它。
<app-user-form [user]="user" (submit)="edit($event)">
</app-user-form>
<app-user-form (submit)="add($event)">
</app-user-form>
如果我们从
user
点开始组件托管在其自己的模块中我不认为分解该表单及其包装器会增加太多捆绑包大小。
// user-form.component.ts
@Component({
selector: 'app-user-form',
template: `
<form [formGroup]="userForm" (submit)="submit.next($event)">
<label>Username</label>
<input type="text" formControlName="username" />
<label>Password</label>
<input type="password" formControlName="password" />
<!-- ... -->
<button type="submit" > {{ mode === 'edit' ? 'Edit' : 'Add' }} </button>
</form>
`
})
export class UserFormComponent {
@Input() set user(user: User) {
this.userForm.patchValue({...user})
}
@Input() mode : 'edit' | 'add';
@Output() submit = new EventEmitter<User>();
userForm = new FormGroup({
username: new FormControl('', [Validators.Required, UserNameValidator]),
password: new FormControl('', [Validators.Required, PasswordValidator]
// ...
})
}
做:
// user-form.component.ts
@Component({
selector: 'app-user-form',
template: `
<form [formGroup]="userForm" (submit)="submit.next($event)">
<label>Username</label>
<input type="text" formControlName="username" />
<label>Password</label>
<input type="password" formControlName="password" />
<!-- ... -->
<button type="submit" > {{ submitLabel }} </button>
</form>
`
})
export class UserFormComponent {
@Input() set user(user: User) {
this.userForm.patchValue({...user})
}
@Input() submitLabel = 'Save';
@Output() submit = new EventEmitter<User>();
userForm = new FormGroup({
username: new FormControl('', [Validators.Required, UserNameValidator]),
password: new FormControl('', [Validators.Required, PasswordValidator]
// ...
})
}
<app-user-form [user]="user"
[submitLabel]="'Edit'"
(submit)="edit($event)">
</app-user-form>
<app-user-form [submitLabel]="'Add'"
(submit)="add($event)">
</app-user-form>
这种方法特别允许我们提供默认翻译,或使用自定义翻译而不触及原始 user-form.component.ts
// user-form.component.ts
@Component({
selector: 'app-user-form',
template: `
<form [formGroup]="userForm" (submit)="submit.next($event)">
<ng-content></ng-content>
</form>
`
})
export class UserFormComponent implements IUserFormComponent {
private value: User;
@Input() set user(user: User) {
this.value = user;
this.userForm.patchValue({...user})
}
@Output() submit = new EventEmitter<User>();
// IUserForm
userForm = new FormGroup({
username: new FormControl('', [Validators.Required, UserNameValidator]),
password: new FormControl('', [Validators.Required, PasswordValidator]
// ...
})
reset() {
this.user = this.value;
}
}
// user-form-n-field.component.ts
@Component({
selector: 'app-user-n-field',
template: `
<label> {{ usernameLabel }} </label>
<input [control]="control" />
`
})
export class UserFormNFieldComponent {
@Input() label = 'n';
control: AbstractControl;
constructor(userFormComponent: IUserFormComponent) {
this.control = this.userFormComponent.userForm.controls.n;
// maybe subscribe the userForm changes
// or add extra validations
}
}
最终的用法可能如下所示:
<app-user-form #form [user]="user"
(submit)="edit($event)">
<!-- ... -->
<app-user-form-avatar-field></app-user-form-avatar-field>
<app-user-form-username-field></app-user-form-username-field>
<app-user-form-password-field></app-user-form-password-field>
<!-- ... -->
<button type="button" (click)="form.reset()" >Reset</button>
<button type="submit" >Edit</button>
</app-user-form>
<app-user-form [user]="user"
(submit)="add($event)">
<app-user-form-username-field></app-user-form-username-field>
<app-user-form-enabled-field></app-user-form-enabled-field>
<!-- ... -->
<button type="submit" >Add</button>
</app-user-form>
关于angular - 如何对组件类应用单一职责?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50863564/
我想在单个 View 中显示文本、图像。也请帮助我 我想从我的类(class)而不是 xml 提供图像的 src 请帮助谢谢 最佳答案 你可以为此使用Button Button b=new Butto
我有一个消息模型,管理员和用户都可以创建消息。但对于管理员和用户来说,有单独的模型,称为管理员和用户。 消息模型有一个名为“created_by”的列,用于存储创建者的 ID。现在的问题是我如何与 M
我无法为菜单资源充气,并且无法将其附加到我的 Activity 的工具栏上。 这似乎很简单,但是我想我缺少明显的东西。我正在使用NavGraph,所以我不知道这是否影响工具栏? 有人看到我做错了吗?
我正在开发一个应用程序,它有一个 MainActivity 并且有许多用于医院、诊所的 ImageViews ... 当按下其中一个时,它会带你到一个新的 Activity DisplayActivi
我会尽量保持简短,但我需要一些建议。 我所在的团队正在并行开发适用于 android、iphone 和 wp7 的应用程序。我们有一个设计团队,可以为所有三个平台提出一个单一的设计。 最新应用程序的设
我正在使用 Josh Smith 中的示例.他有一个显示 CustomerViewModel 列表的 WorkspaceViewModel。他使用相同的 ViewModel 来显示所有客户和编辑一个客
我是 Azure 新手,正在尝试了解各种服务,目前我正在尝试了解移动服务及其各种功能,例如身份验证和推送。 移动服务是否仅支持一种操作系统上的一个应用程序,还是可以在多个操作系统(Android、iO
我在 Stoyan Stefanov 的书中读到了关于单一变量模式的内容。 JSLint 也很好。 但我在我的代码中注意到我可能会重载此模式。整个我的 .js 文件,整个脚本只是一个大变量。 例如:
我想在一个 View 中添加多个具有不同不透明度的阴影。阴影的规范如下: Y 偏移量为 4,模糊半径为 1 Y 偏移量为 10,模糊半径为 10 Y 偏移量为 2,模糊半径为 4 1 的模糊半径,1
我们有几个 API,我们希望通过客户端凭据流授予对客户端的访问权限。流程会像这样。 客户端根据某个范围从 is4 获取 token 客户端使用 token 访问第一个 API 客户端需要使用相同的 t
我是 ruby on rails 的新手。我正在尝试在 ruby on rails 上设计一个注册表单,该表单具有 Basic 和 Paid 用户的单选按钮。当用户点击付费并点击提交时,应该会
我用 Entity Framework 6 开发了一个项目,该项目使用 MySQL 作为数据库。在我的 Windows 系统上,该项目正在运行。现在我试图在我的 linux 机器上移动那个项目。为了运
我正在为我的电子商务应用程序创 build 计。它将拥有由 AWS Lambda 支持的多项服务。 Orderservice、InventoryService、PaymentService、Loggi
我目前正在开发一个执行以下操作的单 View 应用程序: 使用 CoreLocation 获取用户位置 将他们的经/纬度发送到 API 以 JSON 格式返回潮汐数据 深入研究 JSON 中的对象和键
我想托管各种 Angular2 应用程序,这些应用程序使用相同的框架包和来自根域和子域的 node_modules: domain.com subdomain.domain.com sub2.doma
我正在尝试使用 Git Publisher 插件来标记带有 $BUILD_TAG 的成功构建,但我无法找出它将接受的 Target remote name 的值。如果我在 GIT 配置中使用 Repo
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 8年前关闭。 Improve thi
有一个带有许多控件的 View (窗口),以简化: 此 View 用于显示和编辑多个配置: public class ViewModel: INotifyPropertyChanged
我有一个 textView 和类似的文本 “这是带有 KeyWord 和 Link 浏览的简单文本” 在上面的文字中我想制作.. 点击链接可打开该网址和点击该关键字在我的应用程序中打开一个新 Acti
我在我现有的应用程序中有一个任务,我们有 2 个不同的数据库,一个在 SQL Server 中,另一个在 Oracle 中,但是两个模式是相同的。 目前我们有一个使用 Entity Framework
我是一名优秀的程序员,十分优秀!