2014-09-27 59 views
0

問題:在下面的設置中,是否有一種方法可以在不將$ 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模型對象中的值。

那麼,這是爲什麼?有沒有辦法讓沒有注射所需的功能

編輯:所以真正的問題是:爲什麼我必須調用$範圍$適用()這裏爲什麼觀點沒有改變,沒有它

+0

如果您希望在視圖中顯示內容,則需要注入$ scope。另外就像旁註一樣,不需要爲依賴注入使用數組表示法。 – alexrogins 2014-09-27 08:45:43

+0

當使用「controller as」語法時,在視圖中顯示的東西沒有顯式注入的範圍。 (http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/)如果我已經正確理解使用「控制器爲」的一點是顯式$ scope注入是不需要。 – finn 2014-09-27 09:09:54

+0

至於說明,文檔說,如果顯式$ inject,js minifies/uglifier會破壞代碼,或者不使用數組符號。 (http://code.angularjs.org/1.2.25/docs/guide/di)這就是爲什麼我一直在使用它。 – finn 2014-09-27 09:13:40

回答

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()角度同步你的綁定。在大多數應用程序被自動調用後,在你的構造函數代碼之後,或者在你提供給角碼的大多數回調之後。但是,如果您有第三方庫不會自動爲您自動應用,則需要自行完成。所以你要麼注入範圍,以便你可以在這裏申請,或者你需要讓你的navigator(這似乎是一個全球變量)角度服務,並使這一個電話適用於你。

+0

好的,謝謝。我想我明白。我將不得不嘗試提供這項服務。導航器變量來自瀏覽器。我不會在代碼中的任何地方創建它。http://www.w3schools.com/html/html5_geolocation.asp – finn 2014-09-27 09:39:55