【问题标题】:Textarea to ignore enter but need to trigger Save buttonTextarea 忽略输入但需要触发保存按钮
【发布时间】:2017-09-30 19:51:06
【问题描述】:

有点棘手的情况。对于下面的代码,我添加了 (keydown.enter)="false" 以忽略 textarea 中的换行/输入按钮

这会导致用户出现问题,并且希望现有的行为按下回车会自动触发“保存按钮”

知道如何在仍聚焦于 textArea 但忽略断线时触发保存按钮吗?

    <textarea #textArea
    style="overflow:hidden; height:auto; resize:none;"
    rows="1"
    class="form-control"
    [attr.placeholder]="placeholder"
    [attr.maxlength]="maxlength"
    [attr.autofocus]="autofocus"
    [name]="name"
    [attr.readonly]="readonly ? true : null"
    [attr.required]="required ? true : null"
    (input)="onUpdated($event)"
    [tabindex]="skipTab ? -1 : ''"
    (keydown.enter)="false"
    [(ngModel)]="value">
    </textarea >

【问题讨论】:

  • 有什么帮助吗?这看起来比我想象的要棘手
  • AngularJS 和 Angular 是有区别的。如果您指定正确使用的问题,它将对您的问题有所帮助。 (它看起来像 Angular,对我来说也称为 Angular 2。)
  • @hirse 已更新。是的,它是角 2
  • 您能否进行编辑并提供有关您的文件结构的更多详细信息?我在答案中看到了很多来自您的 cmets,但仍不清楚。请给出您的组件结构:)

标签: javascript html angular textarea


【解决方案1】:

@Pengyy 扩展答案

您可以将绑定回车键绑定到一个伪保存函数,并在其中阻止默认,从而阻止保存函数和换行符。然后你可以从那里调用 save 函数(假设它是可访问的,例如服务),或者你可以发出一个 EventEmitter,并让该发出被捕获以触发 Save 函数。

【讨论】:

    【解决方案2】:

    您可以将Save按钮的相同功能绑定到texterea的keydown.enter,并调用$event.preventDefault避免换行。

    样本plunker

    【讨论】:

    • 问题是我的 save() 在另一个文件中。文本区域在它自己的控制文件中。
    • @ove 另一个文件意味着另一个组件?你可以参考angular.io/docs/ts/latest/cookbook/component-communication.html
    • @Penyy 这个控件到处都在使用,看起来我需要处理 onenterkey 事件并到处调用 save 。如果可能的话,我会尽量避免这种情况
    • @ove 好的,那么你可以用form 包装元素,并将save 绑定到表单的keydown.enter。我已经更新了 plunker。
    • 将 key.onenter 事件放在整个表单上会导致选项卡和按钮出现问题。如果您选择一个按钮并输入。它保存了表单,但应该打开一个模型。
    【解决方案3】:

    假设您的 textareaform 元素内。

    {Plunker Demo}

    您可以通过使用隐藏提交输入来实现它,像这样

    @Component({
      selector: 'my-app',
      template: `
        <form (submit)="formSubmitted($event)">
          <input #proxySubmitBtn type="submit" [hidden]="true"/>
    
          <textarea #textArea (keydown.enter)="$event.preventDefault(); proxySubmitBtn.click()">
        </textarea>
        </form>
      `,
    })
    export class App {
      formSubmitted(e) {
        e.preventDefault();
        alert('Form is submitted!');
      }
    }
    

    【讨论】:

    • 不明白有什么相似之处,能不能详细说明一下这个问题
    • 我的 textarea 控件封装在不同的文件中。提交按钮在另一个区域/文件中。
    • 但您仍然可以在您的 textarea 旁边添加另一个 submit input。事实上,您可以拥有任意数量的submit 按钮/输入。你试过这个吗?
    • 我不明白为什么我需要在我的输入中有提交按钮。我需要调用正确的提交按钮
    【解决方案4】:

    您可以创建一个服务,该服务可以向将处理该命令的其他组件发送通知。该服务可能如下所示:

    import { Injectable } from "@angular/core";
    import { Subject } from "rxjs/Subject";
    
    @Injectable()
    export class DataSavingService {
    
        private dataSavingRequested = new Subject<void>();
        public dataSavingRequested$ = this.dataSavingRequested.asObservable();
    
        public requestDataSaving(): void {
            this.dataSavingRequested.next();
        }
    }
    

    ...并且应该在模块的providers 部分中注册。注意:如果必须在通知中传递数据,您可以为dataSavingRequested Subject 声明一个非空参数类型(例如string)。

    服务将被注入到带有 textarea 元素的组件中,并在 Enter 按键事件的处理程序中调用:

    import { DataSavingService } from "./services/data-saving.service";
    ...
    
    @Component({
        template: `
            <textarea (keypress.enter)="handleEnterKeyPress($event)" ...></textarea>
        `
    })
    export class ComponentWithTextarea {
        constructor(private dataSavingService: DataSavingService, ...) {
            ...
        }
    
        public handleEnterKeyPress(event: KeyboardEvent): void {
            event.preventDefault(); // Prevent the insertion of a new line
            this.dataSavingService.requestDataSaving();
        }
        ...
    }
    

    带有保存按钮的组件将订阅服务的dataSavingRequested$通知,并在收到通知时保存数据:

    import { Component, OnDestroy, ... } from "@angular/core";
    import { Subscription } from "rxjs/Subscription";
    import { DataSavingService } from "../services/data-saving.service";
    ...
    
    @Component({
        ...
    })
    export class ComponentWithSaveButton implements OnDestroy {
    
        private subscription: Subscription;
    
        constructor(private dataSavingService: DataSavingService, ...) {
            this.subscription = this.dataSavingService.dataSavingRequested$.subscribe(() => {
                this.saveData();
            });
        }
    
        public ngOnDestroy(): void {
            this.subscription.unsubscribe();
        }
    
        private saveData(): void {
            // Perform data saving here
            // Note: this method should also be called by the Save button
            ...
        }
    }
    

    上面的代码假定必须在组件中使用保存按钮执行保存。另一种方法是将该逻辑移动到服务中,这将公开一个可由组件调用的saveData 方法。但是,该服务需要收集数据以保存。它可以通过 Subject/Observable 机制获得,也可以直接由组件作为参数提供给saveData 或通过调用服务的其他方法。

    【讨论】:

    • 谢谢。我希望有更简单的东西。我将需要稍微更改代码并在不同区域进行大量重新测试
    • @ove - 我添加了另一个关于实施服务以保存数据的建议。
    【解决方案5】:

    可能有两种解决方案:

    1. 使用javascript处理输入事件并触发其中的保存功能

    1. 在 Angular 端使用与 this 中描述的相同的东西。

    This 也可以帮到你

    【讨论】:

      猜你喜欢
      • 2020-08-07
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 2014-11-08
      • 2017-06-21
      • 2011-06-13
      相关资源
      最近更新 更多