【问题标题】:AngularJS + TinyMCE: ng-maxlength is not working on <textarea>AngularJS + TinyMCE:ng-maxlength 不适用于 <textarea>
【发布时间】:2016-01-14 15:33:13
【问题描述】:

我想限制最大文本长度,使其不超过数据库中的列长度。我已经在后端设置了这个限制,现在我想在前端强制执行它。

我使用TinyMCE v4.3.3 和angular-ui-tinymce v0.0.12 插件和AngularJS v1.4.6。

JS:

var tinymceOpts = {
    toolbar: false,
    menubar: false,
    // do not add <p></p> from the start:
    forced_root_block: ''
}

HTML:

<textarea ui-tinymce="tinymceOpts"
          ng-model="body"
          name="body"
          ng-maxlength="100"
          required>
    {{ body }}
</textarea>
<span ng-show="form.body.$error.maxlength" class="error">
    Reached limit!
</span>

如你所见,我这里使用ng-maxlength属性来限制&lt;textarea&gt;的长度。

预期结果: 验证输入并仅在内容长度(包含标签) 超过限制(本例中为 100 个字符)时显示错误消息。

实际结果:

当输入包含一些文本(无论长度如何)时,表单输入状态设置为无效。


计算字符数(右下角)用于测试:

this.getCharCount = function() {
    var tx = editor.getContent({format: 'raw'});
    return tx.length;
};

【问题讨论】:

标签: angularjs tinymce textarea ng-maxlength angular-ui-tinymce


【解决方案1】:

这里的问题是 TinyMCE 使用自己的&lt;iframe&gt; 来编辑文本内容并在特殊事件中将它们写回您的&lt;textarea&gt;。 难怪ng-maxlength 在这里不起作用。

为了达到您想要的效果,您需要检查编辑器内容本身,并在达到最大长度时禁止输入更多字符。

【讨论】:

  • 我正在为 TinyMCE 使用 AngularJS 包装器,它将文本内容绑定到模型。所以ng-maxlength 指令甚至不应该知道&lt;iframe&gt;。我在设置模型中的字符数限制时遇到了麻烦。我尝试编写一个自定义 TinyMCE 插件来计算字符,但我遇到了另一个问题(Data URIs are shorter inside TinyMCE 然后在模型中,我得到了错误的内容长度)
  • 所以你想计算所有东西(包括标签代码)?你能详细说明一下 - 我想我可能有一个解决方案(但时间不多)
  • 是的,我想限制最大文本长度,使其不超过数据库中的列长度。我已经在后端设置了这个限制,现在我想在前端强制执行它。请不要打扰自己,并在您有更多空闲时间时发布解决方案。我已经有一个与启用的 SCE 一起使用的解决方案(我编写了一个自定义的maxlength Angular 指令),稍后会发布它。
  • 我的解决方案会很昂贵(及时),因为您需要在每次用户执行编辑器操作时检查编辑器内容长度。如果超过最大长度,编辑器内容将重置为之前的状态(撤消步骤)。
【解决方案2】:

我设法让它工作了!必须在 AngularJS 中禁用 SCE 模式:

angular.module('myApp', ['ui.tinymce'])
.config(['$sceProvider', function($sceProvider) {
    $sceProvider.enabled(false);
}])
.controller('myCtrl', ['$scope', function($scope) {
    // ...
}]);

jsFiddle

!当心安全漏洞!

严格上下文转义 (SCE) 是一种模式,其中 AngularJS 需要在某些上下文中进行绑定以产生一个标记为可安全用于该上下文的值。禁用 SCE 后,AngularJS 应用程序允许将任意 HTML 渲染到 &lt;div&gt;,并且渲染用户控制的输入会产生安全漏洞。

【讨论】:

    【解决方案3】:

    我相信您真正想要的是让 TinyMCE 指令计算可见字符的“长度”,而不是计算 &lt;textarea&gt; 中的字符。 TinyMCE 将在页面中注入自己的 iFrame,编辑器是该 iFrame 的一部分——它不是&lt;textarea&gt;

    当您对&lt;textarea&gt; 进行验证时,您是在要求Angular 计算&lt;textarea&gt; 中的字符...这对您来说将是一个问题。问题是标准指令只计算字符,因此是一个简单的(空)HTML 示例:

    &lt;p&gt;&lt;/p&gt;

    当实际上没有“可见”内容时,确实会被计为 7 个字符。我为另一个编辑器构建了一个自定义指令,最终我对 HTML 使用了 jQuery 的 .text() 函数。这将删除所有 HTML 标记,并提供编辑器中实际文本字符数的近似值。这是指令中的部分代码:

    var jStrippedString = jQuery(modelValue).text().trim();
    return (maxlength < 0) || ngModelCtrl.$isEmpty(jStrippedString) || (jStrippedString.length <= maxlength);
    

    我相信您会想要创建一个自定义 Attribute 指令,该指令允许您为编辑器获取模型数据并自己执行此验证,而不是简单地计算 &lt;textarea&gt; 中的字符。

    【讨论】:

    • 不,我不知道。我说得很清楚,我需要用标签来计算内容长度。
    猜你喜欢
    • 1970-01-01
    • 2023-01-05
    • 2016-11-29
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多