指令作用域。$watch 在控制器函数之后调用
Directive scope.$watch called after controller function
所以我有一个控制器和指令。我无法理解为什么我的控制器在我的指令之后运行。我已经搜索了堆栈以试图找到答案,但似乎大多数答案都是个案。
我的最简单形式的控制器就是这样
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()
}
}
}};}]);
当我点击我的 ng-click 按钮时,我将转到 gotoLocation 作用域函数并重新定义 $scope.initAddress。我的HTML如下:
<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>
现在,当我查看我的指令时,我正在使用
.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));
});
}
现在,当我点击按钮时,它会运行到控制器和 $scopes.initAddress,但不会点击 $scope.watch。当我再次点击它时,它首先点击 $scope.watch 然后它进入我的控制器并相应地更新。我怎样才能改变它,以便它先击中控制器,然后 $scope.watch 捕捉控制器中的变化。而不是先 运行 $scope.watch 然后 运行 控制器。
感谢您的帮助
当AngularJS 编译DOM 时,它以深度优先、自上而下的方式遍历DOM 树。当它沿着 DOM 走下去时,它会实例化指令控制器。然后,当它到达本地 DOM 树分支的底部时,它开始 link 以自下而上的方式执行指令,同时返回分支。这并不意味着所有指令控制器都是 运行 在所有指令 linking 之前;它只是意味着在本地 DOM 分支中,指令控制器在 linked 之前被实例化。
因此,在您的情况下,$scope.initAddress = {...}
首先被击中。您是否尝试过在 link 函数中初始化地址?
关于理解为什么控制器在我的指令之后运行。
根据 angular$compile 阶段,指令总是在使用深度优先遍历算法的控制器之前调用。
原因是,指令是一个可重用的组件。所以它必须在调用控制器之前实例化。
例如你的 html 可能看起来像这样
<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>
这里的 initAddress 将是各自控制器 "controller1"、"controller2" 和 "controller3" 中的范围变量。因此,总是会在使用深度优先遍历算法的控制器之前调用指令。
这是指令的生命周期
- 指令被实例化
- 调用了声明指令的外部控制器。
- 指令中定义的控制器被调用。
- prelink if defined 被调用。
- postlinkif defined被调用
注意:如果定义了 link 函数,则它始终是 postlink 函数。
如果声明了编译函数,则永远不会调用 link 函数。
请参阅post了解更多详情。
http://yogeshtutorials.blogspot.in/2015/12/angularjs-directive-lifecycle.html
所以我有一个控制器和指令。我无法理解为什么我的控制器在我的指令之后运行。我已经搜索了堆栈以试图找到答案,但似乎大多数答案都是个案。
我的最简单形式的控制器就是这样
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()
}
}
}};}]);
当我点击我的 ng-click 按钮时,我将转到 gotoLocation 作用域函数并重新定义 $scope.initAddress。我的HTML如下:
<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>
现在,当我查看我的指令时,我正在使用
.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));
});
}
现在,当我点击按钮时,它会运行到控制器和 $scopes.initAddress,但不会点击 $scope.watch。当我再次点击它时,它首先点击 $scope.watch 然后它进入我的控制器并相应地更新。我怎样才能改变它,以便它先击中控制器,然后 $scope.watch 捕捉控制器中的变化。而不是先 运行 $scope.watch 然后 运行 控制器。
感谢您的帮助
当AngularJS 编译DOM 时,它以深度优先、自上而下的方式遍历DOM 树。当它沿着 DOM 走下去时,它会实例化指令控制器。然后,当它到达本地 DOM 树分支的底部时,它开始 link 以自下而上的方式执行指令,同时返回分支。这并不意味着所有指令控制器都是 运行 在所有指令 linking 之前;它只是意味着在本地 DOM 分支中,指令控制器在 linked 之前被实例化。
因此,在您的情况下,$scope.initAddress = {...}
首先被击中。您是否尝试过在 link 函数中初始化地址?
关于理解为什么控制器在我的指令之后运行。
根据 angular$compile 阶段,指令总是在使用深度优先遍历算法的控制器之前调用。
原因是,指令是一个可重用的组件。所以它必须在调用控制器之前实例化。
例如你的 html 可能看起来像这样
<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>
这里的 initAddress 将是各自控制器 "controller1"、"controller2" 和 "controller3" 中的范围变量。因此,总是会在使用深度优先遍历算法的控制器之前调用指令。
这是指令的生命周期
- 指令被实例化
- 调用了声明指令的外部控制器。
- 指令中定义的控制器被调用。
- prelink if defined 被调用。
- postlinkif defined被调用 注意:如果定义了 link 函数,则它始终是 postlink 函数。 如果声明了编译函数,则永远不会调用 link 函数。
请参阅post了解更多详情。 http://yogeshtutorials.blogspot.in/2015/12/angularjs-directive-lifecycle.html