我目前有 2 个指令:
- 创建文本框和工具栏 div 的编辑器指令。
- 嵌入到编辑器中的粗体按钮
标记
<editor content="text">
<bold-button>B</bold-button>
</editor>
编辑器指令
.directive('editor', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
'content': '='
},
template: '<div class="editor">' +
'<div class="toolbar" ng-transclude></div>' +
'<textarea ng-model="content"></textarea>' +
'</div>',
controller: function ($scope, $element, $attrs) { },
link: function (scope, elem, attrs, ctrl) {
var editor = new Editor();
editor.onPostUpdateDom = function () {
scope.content = elem.find('textarea').val();
};
// Expose editor to other directives
ctrl.editor = editor;
};
});
粗体按钮指令
.directive('boldButton', function () {
return {
require: '^editor',
restrict: 'E',
replace: true,
transclude: true,
scope: {},
template: '<button type="button" ng-click="format()" ng-transclude>'+
'</button>',
link: function (scope, elem, attrs, editorCtrl) {
scope.format = function () {
editorCtrl.editor.formatCommand("bold");
};
};
});
editor指令使用第三方插件,该插件提供了一种formatCommand()
更改 textarea 值的方法。
粗体按钮指令通过编辑器的控制器触发此方法。
现在,每次插件更改 DOM 时,它都会引发一个onPostUpdateDOM
事件,我使用该事件来获取新值并将其分配给编辑器指令中的范围:
scope.content = elem.find('textarea').val();
这真的很好用。按下按钮,值发生变化。
然而,该插件还通过键盘快捷键提供 DOM 操作。当 DOM 被更改时,该scope.content = elem.find('textarea').val();
行不起作用,因为它发生在 Angular 之外。将该行包装在一个$apply
作品中,但随后formatCommand()
来自按钮指令的调用会引发“应用已在进行中”错误。
这是“安全应用”反模式的案例吗?!