So I have a controller and directive. I am having trouble understanding why my controller runs after my directive. I have scoured stack trying to find the answer but it seems like most of the answers are a case to case basis.
My controller in its simplest form is as so
app.controller('MyCtrl', ['$scope', function ($scope){
$scope.initAddress = {
place_id: "",
geometry: {
location: {
A: "",
F: ""
}
},
}
$scope.gotoLocation = function (placeId) {
$scope.initAddress = {
place_id: "placeId",
geometry: {
location: {
A: placeId.geometry.location.lat(),
F: placeId.geometry.location.lng()
}
}
}};}]);
When I click on my ng-click button I am going to the gotoLocation scoped function and redefining $scope.initAddress. My HTML is as follows:
<div class="row">
<my-map address="initAddress"></my-map>
</div>
<div ng-repeat="place in placelistData.placeList">
<button ng-click="gotoLocation(place.id)">{{place.id}}</button>
</div>
Now when I look at my directive, I am using
.directive('myMap', function () {
return {
restrict: 'E',
replace: true,
scope: {
address: '=?',
},
template: '<div class="dp-places-map-wrapper"><input type="text" class="dp-places-map-input"><div class="dp-places-map-canvas"></div></div>',
link: function (scope, element, attrs) {
scope.$watch('address', function () {
if (map && scope.address)
map.setCenter(getLocation(scope.address));
});
}
Right now, when I click the button it runs to the controller and $scopes.initAddress and doesn't hit $scope.watch. When I click it again, it hits $scope.watch first then it goes to my controller and updates accordingly. How can I change it so that it will hit the controller prior and then the $scope.watch catching the change in the controller. Rather than running $scope.watch first then running the controller.
Thanks for the help
Regarding understanding of why controller runs after my directive.
As per the angular $compile phase, directives are always called before the controllers using depth first traversl algorithm.
The reason being, directive is a reusable component. So it must be instantiated before the controllers are called.
e.g. your html may look like this
<body ng-app="demo">
<div ng-controller="controller1">
<my-map address="initAddress"></my-map>
</div>
<div ng-controller="controller2">
<my-map address="initAddress"></my-map>
</div>
<div ng-controller="controller3">
<my-map address="initAddress"></my-map>
</div></body>
Here initAddress would be the scope variables in the respective controllers "controller1","controller2", and "controller3". Hence always the directives will be called before the controllers using depth first traversl algorithm.
Here is the lifecycle of the directive
Please see the post for more details. http://yogeshtutorials.blogspot.in/2015/12/angularjs-directive-lifecycle.html