问题:如果没有将$ scope注入到以下设置中的Angular“controller as”方法中,是否有办法获得所需的模型更改?
html:
<div data-ng-controller="Buildings as vm">
<select data-ng-model="vm.selected.building"
data-ng-options="building.name for building in vm.buildings"
data-ng-change="vm.changeBuilding()">
</select>
<div data-ng-repeat="building in vm.buildings">
<div data-ng-if="vm.selected.building.name === building.name">
<select data-ng-model="vm.selected.room"
data-ng-options="room.name for room in building.rooms"
data-ng-change="vm.changeRoom()">
<option value=""></option>
</select>
</div>
</div>
</div>
控制器:
angular.module('App').controller('Buildings', ['$scope', 'BuildingService', 'Geolocation',
function ($scope, BuildingService, Geolocation) {
var vm = this;
BuildingService.getAll().then(function (buildings) {
vm.buildings = buildings;
vm.selected = { // defaults
building: buildings[0],
room: null
};
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
vm.selected.building = Geolocation.closest(position, vm.buildings);
vm.selected.room = null;
$scope.$apply(); // <--- Why is that needed?
});
}
vm.changeBuilding = function () {
vm.selected.room = null;
console.log(vm.selected);
};
vm.changeRoom = function () {
console.log(vm.selected);
};
}
]);
解释:我从服务中获取建筑物阵列,然后将第一个建筑物作为默认设置放入范围。然后我计算(使用建筑物的纬度和经度)哪个建筑物最接近我当前的位置,并相应地更改模型对象。
这一切都有效。默认建筑在第一个html选择控件中闪烁,然后更改为最近的建筑物。
但是,当我使用“Controller as”语法时,我发现将$ scope注入控制器很麻烦,因为通常不需要。你看,如果我拿出$ scope。$ apply();行,视图不会改变。它仍显示默认构建,即使vm.selected.building实际上包含最接近的构建。 (当我尝试从第二个html选择中选择一个房间时,第一个更新为vm.selected.building模型对象中的实际值。
那么,为什么呢?有没有办法在没有注射的情况下获得所需的功能?
编辑:所以真正的问题是:为什么我必须在这里调用$ scope。$ apply()?如果没有它,为什么视图不会改变?
答案 0 :(得分:1)
在本节中,您将在回调中更新vm.selected.building
navigator.geolocation.getCurrentPosition(function (position) {
/* See how this is a callback passed to getCurrentPosition that will be executed later */
vm.selected.building = Geolocation.closest(position, vm.buildings);
vm.selected.room = null;
$scope.$apply(); // <--- Why is that needed?
});
在apply()期间,angular会同步绑定。大多数操作应用后自动调用,例如在构造函数代码之后或在您提供给角度代码的大多数回调之后。但是,如果您的第三方图书馆没有自动为您申请$申请,您需要自己这样做。所以你要么必须注入范围以便你可以在这里申请,或者你需要使你的navigator
(这似乎是一个全局变量)成为一个有角度的服务,并让这一个电话适用于你。