如何在AngularJS组件中设置watcher?
How to set watcher in AngularJS component?
我正在使用 NgMap 来显示 google 地图,我需要能够从网站的各个部分更改中心位置。我有 markerService:
angular.module('markerService')
.factory('MarkerService', MarkerService);
MarkerService.$inject = [];
function MarkerService(){
var coords = [
56.936,
23.12
]
var markers = [];
return {
setCoords: setCoords,
getCoords: getCoords,
setMarkers: setMarkers,
getMarkers: getMarkers,
};
function setCoords(a){
coords = a;
}
function getCoords{
return coords;
}
function setMarkers(a){
markers= a;
}
function getMarkers(){
return markers;
}
}
然后我有使用 NgMap 的组件映射:
angular.module('map')
.component('mapComponent', {
templateUrl: 'app/mapComponent/map.html',
controller: mapController
});
mapController.$inject = ['NgMap', 'MarkerService'];
function mapController(NgMap, MarkerService){
var ctrl = this;
ctrl.markers = MarkerService.getMarkers();
ctrl.center = MarkerService.getCoords();
}
}
和模板:
<div class="map_wrapper">
<ng-map default-style="false"
center="{{$ctrl.center}}"
zoom="10"
>
<marker ng-repeat="m in $ctrl.markers" position="{{m.lat}},{{m.lng}}" on-click="$ctrl.openModal()"></marker>
</ng-map>
</div>
如果我使用 MarkerService.setMarkers([...])
更改标记数组,地图上的标记会更新,因为 ng-repeat 设置了观察者,但使用 MarkerService.setCords([...])
更改坐标不会改变地图中心,因为没有观察者。
我尝试使用 ng-bind center="ng-bind='$ctrl.center'"
但逻辑上它不起作用。我确定我必须从组件控制器设置观察者,但无论我尝试什么,我都无法做到。
更新:
做了一些认真的调查并遇到了一些奇怪的行为。
MarkerService.getCoords()
不是 return 坐标的实例,而是值。如果我使用 MarkerService.setCoords(//some value)
更改坐标,它不会反映在之前声明为 var ctrl.center=MarkerService.getCoords();
的变量中,但如果我再次调用 getter,我会得到更新的值。
这很奇怪,因为我之前一直在使用这种 getter 和 setter 方法,并且总是依赖于 getter 会 return 变量实例的事实.
如果你想设置观察者你必须使用$scope
。
为此,您需要将其注入控制器:
MarkerService.$inject = ['$scope'];
然后添加你的观察者:
function MarkerService($scope){
$scope.$watch([...]);
}
但是你的问题似乎不是出自这里,我认为你在错误的对象上设置了坐标,这就是你的地图没有更新的原因。
你是这样做的吗?:
MarkerService.setCoords(coords)
ctrl.center = MarkerService.getCoords();
为了完成@Groben 的回答(因为我遇到了同样的问题...),组件中 $watcher 的正确语法是:
$scope.$watch('$ctrl.my_field', function () {
ctrl.my_function(ctrl.my_field);
});
其中:
- "ctrl"是控制器的默认名称
- 别忘了注入“$scope”!
为了记忆,模板看起来像:
<input type="text" ng-model="$ctrl.my_field" >
我正在使用 NgMap 来显示 google 地图,我需要能够从网站的各个部分更改中心位置。我有 markerService:
angular.module('markerService')
.factory('MarkerService', MarkerService);
MarkerService.$inject = [];
function MarkerService(){
var coords = [
56.936,
23.12
]
var markers = [];
return {
setCoords: setCoords,
getCoords: getCoords,
setMarkers: setMarkers,
getMarkers: getMarkers,
};
function setCoords(a){
coords = a;
}
function getCoords{
return coords;
}
function setMarkers(a){
markers= a;
}
function getMarkers(){
return markers;
}
}
然后我有使用 NgMap 的组件映射:
angular.module('map')
.component('mapComponent', {
templateUrl: 'app/mapComponent/map.html',
controller: mapController
});
mapController.$inject = ['NgMap', 'MarkerService'];
function mapController(NgMap, MarkerService){
var ctrl = this;
ctrl.markers = MarkerService.getMarkers();
ctrl.center = MarkerService.getCoords();
}
}
和模板:
<div class="map_wrapper">
<ng-map default-style="false"
center="{{$ctrl.center}}"
zoom="10"
>
<marker ng-repeat="m in $ctrl.markers" position="{{m.lat}},{{m.lng}}" on-click="$ctrl.openModal()"></marker>
</ng-map>
</div>
如果我使用 MarkerService.setMarkers([...])
更改标记数组,地图上的标记会更新,因为 ng-repeat 设置了观察者,但使用 MarkerService.setCords([...])
更改坐标不会改变地图中心,因为没有观察者。
我尝试使用 ng-bind center="ng-bind='$ctrl.center'"
但逻辑上它不起作用。我确定我必须从组件控制器设置观察者,但无论我尝试什么,我都无法做到。
更新:
做了一些认真的调查并遇到了一些奇怪的行为。
MarkerService.getCoords()
不是 return 坐标的实例,而是值。如果我使用 MarkerService.setCoords(//some value)
更改坐标,它不会反映在之前声明为 var ctrl.center=MarkerService.getCoords();
的变量中,但如果我再次调用 getter,我会得到更新的值。
这很奇怪,因为我之前一直在使用这种 getter 和 setter 方法,并且总是依赖于 getter 会 return 变量实例的事实.
如果你想设置观察者你必须使用$scope
。
为此,您需要将其注入控制器:
MarkerService.$inject = ['$scope'];
然后添加你的观察者:
function MarkerService($scope){
$scope.$watch([...]);
}
但是你的问题似乎不是出自这里,我认为你在错误的对象上设置了坐标,这就是你的地图没有更新的原因。
你是这样做的吗?:
MarkerService.setCoords(coords)
ctrl.center = MarkerService.getCoords();
为了完成@Groben 的回答(因为我遇到了同样的问题...),组件中 $watcher 的正确语法是:
$scope.$watch('$ctrl.my_field', function () {
ctrl.my_function(ctrl.my_field);
});
其中:
- "ctrl"是控制器的默认名称
- 别忘了注入“$scope”!
为了记忆,模板看起来像:
<input type="text" ng-model="$ctrl.my_field" >