2014-10-09 57 views
0

我有一個「狀態選擇」指令,用一個基於countryCode的狀態列表填充select元素。該指令監視countryCode上的更改以更新提供給ng選項的屬性。加載ng-options前更新模型時的選擇選項

我現在想從我的控制器設置model.countryCode和model.sateCode,但是當countryCode更改時填充狀態選擇時,在選項獲得加載的機會之前更新模型值。

我怎樣才能確保select加載選項後,選擇在其ng模型中引用的選項?

這裏是我的指令:

.directive('stateSelect', [ 'CDN_VIEW', 'locationService', function(CDN_VIEW, locationService) { 
    return { 
     restrict: 'E', 
     scope: { 
      'ngModel': '=', 
      'country': '=', 
     }, 
     link: function stateSelect($scope, elements, attrs) { 
      $scope.states = null; 
      function loadCountryStates(countryCode) { 
       if (!countryCode) { 
        return false; 
       } 

       $scope.ngModel = undefined; 
       locationService.getCountryStates(countryCode).then (function getStates(states) { 
        $scope.states = states; 
       }); 
      } 

      $scope.$watch('country', loadCountryStates); 
     }, 
     templateUrl: 'states.html' 
    }; 
} ]) 

模板:

<select ng-model="ngModel" ng-options="s.code as s.name for s in states"> 
    <option value="" disabled>select state</option> 
</select> 

這裏的使用指令:

<state-select ng-model="info.stateCode" country="info.countryCode"> 

這是我在我的控制器正在做:

function setDetectedLocation(location) { 
    $scope.info.countryCode = location.countryCode; 
    $scope.info.stateCode = location.stateCode; 
    $scope.info.city = location.city; 
} 

locationService.getLocation().then(setDetectedLocation, locationError); 

當我手動填充選擇它時,它工作,如果我運行getLocation兩次,當國家的國家已經加載,它也可以。

任何指針?

+0

我通過將控制器的'info.stateCode'從選擇'ngModel'中解除鏈接並觀察前者的變化,改善了情況。這將修復狀態列表的第一個負載,但當國家/地區選擇更改時問題仍然存在。 – jminuscula 2014-10-10 14:46:17

回答

0

我終於解決了這個問題。訣竅是取消關聯控制器模型 - 一個持有真實值的模型 - 和指令的選擇模型 - 持有選定選項的模型。這樣我可以手動觀察兩者的變化並在需要時更新值。

這裏的更改指令:

scope: { 
    'ngModel': '=', 
    'country': '=', 
}, 
link: function stateSelect($scope, element, attrs) { 
    $scope.states = null; 
    $scope.state = { 'code': undefined }; 

    function loadCountryStates(countryCode) { ... } 

    $scope.$watch('country', loadCountryStates); 

    // watch manual change on select 
    $scope.$watch('state.code', function(stateCode) { 
     $scope.ngModel = stateCode; 
    }); 

    // watch further changes to the model 
    $scope.$watch('ngModel', function(stateCode) { 
     if (stateCode) { 
      $scope.state.code = stateCode; 
     } 
    }); 
} 

這裏的更改模板:

<select ng-model="state.code" ng-options="s.code as s.name for s in states"> 
</select> 

注意選擇現在是如何鏈接到指令的state.code,反過來,這是觀看並通過ngModel與控制器屬性同步。

我不知道爲什麼原來的方式不起作用,但!

-2

您可以創建一個initStateTo參數,該參數在設置時將初始化指令中的狀態值。

 $scope.info.initStateTo = "CA"; 

    <state-select ng-model="info.stateCode" country="info.countryCode" 
       initStateTo="info.initStateTo"> 

      $scope.ngModel = undefined; 
      locationService.getCountryStates(countryCode).then (
       function getStates(states) { 
        $scope.states = states; 
        if($scope.initStateTo) { 
         $scope.ngModel = $scope.initStateTo; 
         $scope.initStateTo = undefined; 
        } 
       }); 
+0

對不起,我不認爲我明白這一點。 ngModel和initStateTo範圍屬性之間的區別是什麼?如果兩者都被設置爲相同的值,同時從控制器?這不等同於指令中的$ scope.ngModel = $ scope.ngModel嗎?謝謝。 – jminuscula 2014-10-10 13:40:02

+0

您表示「在選項有機會獲得加載之前更新了模型值」,這是因爲設置國家會導致調用滿足所有狀態的服務。我建議的解決方案將在國家服務已設置所有狀態之後設置狀態值,使得該值是正確的並且在所有值被加載後設置。如果這不是你想要做的,那麼我誤解了這個問題。 – Scott 2014-10-10 17:49:31

+0

我確實嘗試過,但令人驚訝的是countryCode的手錶回調沒有按時被調用。我猜Angular等待摘要週期的末尾來處理回調,所以看起來沒有辦法在模型值設置之前加載選項:\ – jminuscula 2014-10-10 18:18:55

相關問題