I have an angular-bootstrap modal popup box that contains a custom directive in the template:
<div class="modal-header">
<h3 class="modal-title">Modal Header</h3>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<my-directive ng-model="test" ng-change="doSomething()" />
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="upload()">Upload</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
app.controller('ModalCtrl', function ModalCtrl( $scope, $modalInstance ) {
$scope.test = 'empty';
$scope.upload = function() {
$scope.test = 'change!';
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
});
I open the modal popup from my main controller like this:
var app = angular.module( 'myApp', [ 'ui.bootstrap' ] );
app.controller('MainCtrl', function MainCtrl( $scope, $modal ) {
$scope.openModal = function() {
var modalInstance = $modal.open({
templateUrl: '/assets/modals/Modal.html',
controller: 'ModalCtrl',
size: 'md'
});
};
});
As you can see from the above code, the modal template contains my custom directive <my-directive>
which takes $scope.test
- defined in the ModalCtrl
- as it's model and should call $scope.doSomething()
when that model changes.
The custom directive looks like this:
angular.module( 'myApp' ).directive( 'myDirective', function() {
return {
controller: function( $scope ) {
$scope.doSomething = function() {
console.log( 'doSomething() called! $scope.test now = ' + $scope.test );
};
},
link: function( $scope, el, att ) {
console.log( '$scope.test = ' + $scope.test );
},
template: '<div class="thumbnail"></div>'
};
} );
When the modal popup opens the console prints out $scope.test = empty
which is exactly what I expect to see. But when $scope.test
is changed by calling the $scope.upload()
function in ModalCtrl
nothing happens! What I think should happen is $scope.doSomething()
is called which then should print out in the console doSomething() called! $scope.test now = change!
.
Any help would be much appreciated, this is driving me mad!
I figured it out. Instead of using ng-model and ng-change I added:
scope: {
test: '@'
}
to my directive and added this into my link function:
$scope.$watch( 'test', function() {
console.log( 'test changed' );
} );
Then I add test as a parameter in my directives tag like so:
<my-directive test="test" />
and finally whenever I change $scope.test I call $scope.$apply()
and voila!