Apologies if some of the JS is syntactically off. I wrote it while looking at my CoffeeScript
I have a text editor that I've extracted into a directive and I want to share some state between it and its containing template:
Main containing template
<div class="content">
<editor class="editor" ng-model="foo.bar.content" text-model="foo.bar"></editor>
</div>
Template Controller
angular.module('foo').controller('fooController', ['$scope', ... , function ($scope, ...) {
$scope.foo = {}
$scope.foo.bar = {}
$scope.foo.bar.content = 'starting content'
$scope.$watch('foo.bar', function () {
console.log('content changed')
}, true)
}
The template two-way binds on its scope object $scope.foo.bar
with the editor directive. When the text is changed, the editor's 'text-change' handler is fired and a property on the bound object is changed.
Editor Directive
angular.module('foo').directive('editor'), function (
restrict: 'E',
templateUrl: 'path/to/editor.html',
require: 'ng-model',
scope: {
textModel: '='
},
controller: [
...
$scope.editor = 'something that manages the text'
...
],
link: function (scope, ...) {
scope.editor.on('text-change', function () {
$scope.textModel.content = scope.editor.getText()
// forces parent to update. It only triggers the $watch once without this
// scope.$parent.$apply()
}
}
However, changing this property in the directive seems not to be hitting the deep $watch I've set on foo.bar
. After some digging, I was able to use the directive's parent reference to force a $digest cycle scope.$parent.$apply()
. I really shouldn't need to though, since the property is shared and should trigger automatically. Why does it not trigger automatically?
Here are some good readings that I've encountered that are pertinent:
$watch an object
https://www.sitepoint.com/understanding-angulars-apply-digest/