I have a directive which takes an object as parameter. This object can be changed to another one by parent directive. When I use $scope
, then object is updated in the directive. When I use ControllerAs
syntax then reference is broken and change is not reflected. I assumed that in both cases $scope.obj
and vm.obj
are references so they should behave in the same way. What is breaking the reference here and why?
<body ng-app="app" ng-controller="ctrl">
<div>Original object: {{object}}</div>
<button ng-click="changeObject()">Change object!</button>
<my-object obj="object"></my-object>
<my-object-vm obj="object"></my-object-vm>
<script type="text/javascript">
var app = angular.module("app", []);
app.controller("ctrl", function($scope) {
$scope.object = {
p1: "A"
};
$scope.changeObject = function() {
$scope.object = {
p2: "B"
}
}
});
app.directive("myObject", function() {
return {
template: "<div>Obj from scope: {{obj}}</div>",
scope: {
obj: "="
}
}
});
app.directive("myObjectVm", function() {
return {
template: "<div>Obj from vm: {{vm.obj}}</div>",
scope: {
obj: "="
},
controller: function($scope) {
var vm = this;
vm.obj = $scope.obj;
},
controllerAs: "vm"
}
});
</script>
</body>
Plunker: working example
The link is broken because you're copying the reference from the scope to the controller only once, when link()
is invoked. So later, when a new value is assigned to $scope.obj
, the controller still refers to the old one.
You need to use bindToColtroller in addition to controllerAs
:
When an isolate scope is used for a directive (see above),
bindToController: true
will allow a component to have its properties bound to the controller, rather than to scope.