小编Tud*_*las的帖子

markAllAsTouched 和 markAsTouched 都不影响子表单

背景资料

我有一个非常大的表单(可能有数百个字段),我决定将其分解为较小的子表单组件(出于明显的原因)。我使用控制值访问器实现了这一点。这就像一个魅力,直到需要在提交时显示字段上的错误。

子表单的结构如下:

<form [formGroup]="form">
  <app-subform [documentId]="documentId" formControlName="sub-form"></app-subform>

  <!-- Other form fields here ... -->
</form>
Run Code Online (Sandbox Code Playgroud)

为了简化我的工作,我创建了一个错误组件,它将一个控件作为输入,如下面的代码所示。下面的代码是子表单的一部分。

<div class="question">
  <label for="tableNumber">
    Figure/table number
    <app-required [type]="'conditional'"></app-required>
  </label>
  <input type="text" id="tableNumber" formControlName="figure"/>
  <app-error [control]="form.get('figure')"></app-error>
</div>
Run Code Online (Sandbox Code Playgroud)

我的错误 HTML 的内部看起来像这样:

<span class="errorWrapper" *ngIf="control.invalid && control.touched" (click)="clearError()" [innerHtml]="error"></span>
Run Code Online (Sandbox Code Playgroud)

示例代码

虽然我不能完全分享我的完整代码,但这里是问题的重现: https: //stackblitz.com/edit/encapsulated-sub-forms

问题

当我提交代码时,为了在每个输入中显示错误消息,我使用 标记所有输入为触摸this.form.markAllAsTouched();。虽然这对于不属于子表单组件的输入来说就像一个魅力,但子表单组件本身根本不会做出反应,保持不变。

我考虑的解决方案

  • 我的第一反应是 - 为什么不将每个控件单独标记为触摸?不起作用
  • 我为每个触发触摸标记的子表单组件实现一个输入怎么样?没有尝试,看起来更像是一种黑客而不是最佳实践解决方案
  • 将我的实现更改为使用ControlContainer. 看来是最有前途的

我尝试过的

我尝试更改要使用的实现ControlContainer,但这带来了一系列挑战(在单独的堆栈溢出问题中进行了描述)。

我的问题

所以基本上,我想知道的是,如何让我的子表单输入在提交时显示错误,遵循最佳实践并进行最少的重写(我的优先级按此顺序)?

angular angular-forms

6
推荐指数
1
解决办法
6760
查看次数

P12证书"数据不足"错误

我试图使用.p12文件安全地连接到端点但我不断收到以下错误.

_tls_common.js:136
  c.context.loadPKCS12(pfx);
            ^

Error: not enough data
at Error (native)
at Object.createSecureContext (_tls_common.js:136:17)
at Object.TLSSocket._init.ssl.onclienthello.ssl.oncertcb.exports.connect (_tls_wrap.js:1003:48)
at Agent.createConnection (https.js:80:22)
at Agent.createSocket (_http_agent.js:179:26)
at Agent.addRequest (_http_agent.js:141:10)
at new ClientRequest (_http_client.js:147:16)
at Object.exports.request (http.js:31:10)
at Object.exports.request (https.js:197:15)
at Request.start (D:\path_to_project\node_modules\request\request.js:747:30)
Run Code Online (Sandbox Code Playgroud)

生成错误的代码是这样的:

        request({
            method: 'POST',
            url: config.secureEndpoint.hostname + config.secureEndpoint.path,
            body: XMLAPIResponse.body,
            rejectUnauthorized: false,
            strictSSL: false, 
            agentOptions: {
                //pfx: pfx,
                pfx: 'string_path_to_the_p12_key_file.p12',
                passphrase: 'redacted_password'
            }
        }, function (error, response, body) {
            console.log(response);
            if (response.satusCode == 200) {
                model.updateStatus(ID, 'done');
            } else …
Run Code Online (Sandbox Code Playgroud)

https node.js

5
推荐指数
1
解决办法
1242
查看次数

角度输入设置器仅触发一次

我想在问题前面加一个词,说我已经阅读并理解了其他可能重复的问题(例如这个问题),并且无法进行这项工作,使我相信问题本质上有点不同,或者我误解了一些东西。

上下文:我有一个带有两个子组件的父组件(一个侧面菜单和一个主视图)。侧面菜单中有一些过滤器,形式是复选框,通过复选框绑定到对象,[(ngModel)](ngModelChange)="changeFilter()"在模板内使用触发事件。

在父组件中,我捕获了事件:(filter)="updateFilters($event)"。此函数更改一个公共过滤器变量,然后将其传递给其他子组件,如下所示:[filterObject]="filters"

在主视图组件中,我将filterObject变量输入管道,以过滤对象数组。

问题:在我第一次更换过滤器后,管道仅被调用一次。这样显示时,主视图中的filterObject变量显示正确更新,{{filterObject | json}}但从未调用setter。在setter和getter中放置的控制台日志显示只有getter可以访问(2-4)

我尝试过的解决方案:

  • 向管道添加其他参数以触发它。这种方法的问题在于,需要从filterObject不会被调用的设置器中设置新日期-如上所述

  • 使管道不纯净(可行但不是一个很好的解决方案,因为它使每次单击处理2至4次非常大的复杂对象数组)

  • 使父级更新过滤器变量不是通过赋值运算符,而是通过Object.assign它来更改引用并可能触发设置器

我正在考虑的解决方案:如果我无法弄清楚问题出在哪里,我正在考虑提供一种通过观察者在两个组件之间进行通信的服务。否则,我可能不得不适应嵌入了一些自定义更改检测的不纯管道(我正在考虑将过滤器对象转换为JSON字符串并检查长度)。

side-menu-component.html

<input type="checkbox" id="filter-type-2" name="filter-type-2" [(ngModel)]="filterObject.type.me" (ngModelChange)="changeFilter()">
Run Code Online (Sandbox Code Playgroud)

侧面菜单组件

 @Output() filter = new EventEmitter();
 public filterObject = {
    type: {
        mo: true,
        me: true,
        ar: true,
        cto: true,
        gl: true,
        dl: true
    },
    status: {
        unreviewed: true,
        approved: true,
        other: true
    }
};

// ...

changeFilter() {
    this.filter.emit(this.filterObject);
}
Run Code Online (Sandbox Code Playgroud)

parent-component.html

<aside> …
Run Code Online (Sandbox Code Playgroud)

setter typescript angular-decorator angular

3
推荐指数
1
解决办法
2886
查看次数