[英]AngularJS handling different types of DOM manipulation
我目前有2條指令:
標記
<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");
};
};
});
編輯器指令使用第三方插件,該插件提供用於更改textarea值的formatCommand()
方法。
粗體button指令通過編輯器的控制器觸發此方法。
現在,每次插件更改DOM時,它都會引發一個onPostUpdateDOM
事件,我使用該事件來獲取新值並將其分配給editor指令內的作用域:
scope.content = elem.find('textarea').val();
這真的很好。 按下按鈕,數值改變。
但是,該插件還通過鍵盤快捷鍵提供了DOM操作。 更改DOM后, scope.content = elem.find('textarea').val();
行不起作用,因為它發生在Angular之外。 在$apply
包裝該行是formatCommand()
但隨后來自button指令的formatCommand()
調用將引發“應用已在進行中”錯誤。
這是“安全應用”反模式的情況嗎?
編輯器指令中的這些行:
editor.onPostUpdateDom = function () {
scope.content = elem.find('textarea').val();
};
就是這個問題, onPostUpdateDom
事件處理程序會從Angular世界內部或外部觸發,並且由於依賴第三方插件而不受開發人員的控制。
為了解決這個問題,我們本質上需要一個安全的應用程序來處理Angular和Non-Angular事件:
請參見: AngularJS:在調用$ scope。$ apply()時防止錯誤$ digest已經在進行中
因此,答案是將代碼包裝在$timeout
。
即
editor.onPostUpdateDom = function () {
$timeout(function () {
// anything you want can go here and will safely be run on the next digest.
scope.content = elem.find('textarea').val();
});
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.