ui-ace
ui-ace copied to clipboard
editor.insert doesn't appear to trigger model change
I'm trying to create some actions to insert pre-defined text into the editor, but it doesn't appear to cause the model to change.
template:
in controller:
editor.insert("text to insert");
this is not causing the updateDefinition() method to be called.
+1
Seems to work for me fine. You need to tap into the onLoad
callback, like so,
<div ui-ace="{ onLoad : vm.aceLoaded, mode: vm.script.type }"></div>
this.aceLoaded = (editor) => {
editor.insert(script.body)
}
Here is a plunker that reproduces the issue
http://plnkr.co/edit/wZ2uuUGhYfEltWsQGN6R?p=preview
Notice that when you type into the editor, the model is updated and is reflected in the pre tag.
However, when you click the button, the editor is updated but the model is not. The model will not be updated again until you type into the editor.
var app = angular.module('x', ['ui.ace']);
app.controller('FooCtrl', function () {
var editor;
this.message = "";
this.onAceLoaded = function (acee) {
editor = acee;
};
this.doInsert = function () {
if (!editor) return;
editor.insert('Hello');
};
})
<section ng-controller="FooCtrl as foo">
<div ui-ace="{ onLoad: foo.onAceLoaded }" ng-model="foo.message"></div>
<button ng-click="foo.doInsert()">Click Me</button>
<hr>
<pre>{{ foo.message }}</pre>
<hr>
</section>
I've created a workaround here: http://plnkr.co/edit/7Mo7BE3vEIdOvh41Jqfe?p=preview
app.directive('fixAceInsert', function ($parse) {
return {
restrict: 'A',
require: ['ngModel', 'fixAceInsert'],
link: function (scope, el, attrs, ctrls) {
var ngModel = ctrls[0];
var fixAceInsert = ctrls[1];
fixAceInsert.cb = $parse(attrs.fixAceInsert)(scope);
fixAceInsert.ngModel = ngModel;
if (fixAceInsert.cb && fixAceInsert.editor) {
fixAceInsert.cb(fixAceInsert.editor);
}
},
controllerAs: 'uiAceInsertFix',
controller: function () {
var self = this;
this.onAceLoaded = function (editor) {
self.editor = editor;
if (self.cb) {
cb(editor);
}
editor.on('change', function (event) {
if (!self.ngModel) {
return;
}
if (event.data.action !== 'insertText') {
return;
}
self.ngModel.$setViewValue(editor.getValue());
});
};
}
};
});
<section ng-controller="FooCtrl as foo">
<div ui-ace="{ onLoad: uiAceInsertFix.onAceLoaded }"
ng-model="foo.message"
fix-ace-insert="foo.onAceLoaded"></div>
<button ng-click="foo.doInsert()">Click Me</button>
<hr>
<pre>{{ foo.message }}</pre>
<hr>
</section>
I'm having this issue as well.
+1 We also have this issue. Please fix this.
I've submitted a patch for this in #124
Also had the issue (created and now closed a duplicate item). Also same as #133, but he seems to have a (unpushed) solution.
+1 Any update on this issue? It's 18 months old :(
+1 Any update on this?
I have used following code for me,
$scope.aceOptions = {};
//Ace Editor instance on change
$scope.aceOptions.onChange = function(_editor){
//on change get current value
$scope.content = $scope.aceEditor._session.getValue();
};
//Ace Editor instance as first argument
$scope.aceOptions.onLoad = function(_editor){
$scope.aceEditor._editor = _editor;
$scope.aceEditor._session = _editor.getSession();
};
//on event click used the following lines
if($scope.aceEditor && $scope.aceEditor._editor){
//Inserts text into wherever the cursor is pointing.
$scope.aceEditor._editor.insert(imageTag);
}
And view side
<div ui-ace="aceOptions" ng-model="content"></div>
Hope this will help you !
My quick and dirty way of doing it
In controller:
editor.insert("text to insert");
angular.element(editor.container).controller('ngModel').$setViewValue(editor.getValue());