2013-08-11 18 views
5

Czy ktoś może mi pomóc, aby mój przykład działania polegał na rezygnacji z kraju/stanu?Angularjs wyzwalać zależność od państwa członkowskiego

Celowo utworzyłem JSON w ten sposób, ponieważ chcę, aby zależność była ogólna, więc byłbym w stanie zastosować ją w dowolnym menu rozwijanym podczas używania tylko danych meta, a nie HTML.

Oto a link aby zobaczyć przykład kodu w JSFidlle

HTML

Country:<select data-ng-model="Countries" data-ng-options="country.id as country.name for country in Countries.items"> 
      <option value="">Please select a country</option> 
     </select> 

State: <select data-ng-model="currentItem" data-ng-options="item.id as item.name for item in currentStates.items"> 
      <option value="">Please select a state</option> 
     </select> 

kod JavaScript:

function Controller($scope) { 

var Countries = { 
    "id": "field10", 
    "items": [{ 
       "id": "10", 
       "StateGroupID":"0", 
       "name": "United State" 
       }, 
       { 
       "id": "2", 
       "StateGroupID":"1", 
       "name": "Canada" 
       }] 
}; 

var States = 
    { "id": "field20", 
     "StateGroups": [{ 
      "items": [{ "id": "1", 
         "name": "Alabama" 
         }, 
         { 
          "id": "2", 
          "name": "Alaska" 
         }, 
         { "id": "3", 
         "name": "Arizona" 
         }, 
         { "id": "4", 
         "name": "California" 
         }]}, 

       [{ "id": "201", 
        "name": "Alberta" 
        }, 
        { 
         "id": "202", 
         "name": "British Columbia" 
        }, 
        { 
         "id": "303", 
         "name": "Manitoba" 
        }, 
        { 
         "id": "304", 
         "name": "Ontario" 
        }]] 
}; 

$scope.Countries = Countries; 
$scope.currentStates = States.StateGroups[0]; 
$scope.$watch('currentStates', function(value, oldValue){ 
    //alert(value); 
    //alert(JSON.stringify(value)); 
    //$scope.currentStates = (value == "10") ? States.StateGroups[0] : States.StateGroups[1]; 
}); 

}

Odpowiedz

7

pierwsze, myślę, że jest trochę pomyłka w JSON, trzeba mieć jeden „pozycje” przed stanach kanadyjskich

  {"items": [{ "id": "201", 
        "name": "Alberta" 
        }, ..... 

Po wykonaniu tej czynności, chciałbym zmodyfikować kod HTML, aby mieć 2 różne nazwy modelu (tak jak Ty, przy pierwszym kliknięciu nadpisujesz listę krajów). Wtedy będę używać innej składni dla NG-repeat, w celu wymuszenia wartości do StateGroupId

<select data-ng-model="selectedCountry"> 
      <option ng-repeat='country in Countries.items' value='{{country.StateGroupID}}'>{{country.name}}</option>   
     </select> 

Rozwiązanie to pozwala utworzyć funkcję, aby uzyskać stany wybranego ID grupy:

$scope.getStates=function(){ 
    console.log($scope.selectedCountry) 
    return $scope.backupStates.StateGroups[$scope.selectedCountry].items; 
} 

Następnie można użyć tej funkcji, aby wyświetlić je za pomocą nG-repeat

  <select data-ng-model="selectedState" > 
       <option value="">Please select a state</option> 
       <option ng-repeat='state in getStates()'>{{state.name}}</option> 
      </select> 

zmodyfikowałem swój skrzypce tutaj: http://jsfiddle.net/DotDotDot/TsxTU/14/, mam nadzieję, że jest to rodzaj zachowania ty wante d :)

+0

swoją odpowiedź był dla mnie bardzo przydatny. Skierowałeś mnie do błędu w strukturze JSON, a także HTML, który pomógł mi lepiej zrozumieć moje błędy i jak je naprawić, a ostatecznie sprawić, by mój przykład zadziałał. Twój przykład jest lepszy niż mój, ale ** dlaczego użyłeś [ng-repeat] zamiast [ng-options] **? – Scription

+0

Cieszę się, że ci pomogło. Pierwsze powtórzone powtórzenie, którego użyłem, to głównie wymuszenie atrybutu "value" dla każdego elementu. Ułatwia to modyfikowanie podczas testowania, ale możesz sprawić, by działał z opcjami ng. Po drugie, byłem leniwy i skopiowałem/wkleiłem dużą część 3 powtórzeń ng-powtórzeń;). Krótko mówiąc, możesz użyć opcji ng, jeśli chcesz, zadziała to również :) – DotDotDot

7

Proponuję trochę refaktoryzacji twojego modelu danych - wydaje się zaplątany. Niech Store powiatów i stwierdza w dwóch tablic:

$scope.countries = [{ 
    "name": "USA", 
    "id": 1 
    },{ 
    "name": "Canada", 
    "id": 2 
}]; 
$scope.states = [{ 
    "name": "Alabama", 
    "id": 1, 
    "countryId": 1 
    }, { 
    "name": "Alaska", 
    "id": 2, 
    "countryId": 1 
    }, { 
    "name": "Arizona", 
    "id": 3, 
    "countryId": 1 
    }, { 
    "name": "Alberta", 
    "id": 4, 
    "countryId": 2 
    }, { 
    "name": "British columbia", 
    "id": 5, 
    "countryId": 2 
}]; 

Mając to możemy napisać select s dla danych:

<select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="updateCountry()"> 
    <option value="">Select country</option> 
</select> 
<select data-ng-model="state" data-ng-options="state.name for state in availableStates"> 
    <option value="">Select state</option> 
</select> 

Szkoda, że ​​nie możemy używać if wyrażeń w selektorów - jeśli możemy, nie potrzebujesz jednej linii JS! Ale potrzebujemy:

$scope.updateCountry = function(){ 
    $scope.availableStates = []; 

    angular.forEach($scope.states, function(value){ 
    if(value.countryId == $scope.country.id){ 
     $scope.availableStates.push(value); 
    } 
    }); 
} 

I to wszystko. Here is a working plunk for you.

+2

Jeśli do stanów dodawany jest kod kraju, znacznie łatwiej jest użyć filtru: ng-options = "state.name for state in states | filter: {country: countryCode} " – Niki

+0

Prawdopodobnie powinien używać value.countryId === $ scope.country.id jako ścisłej równości. – TGarrett

5

Najprostszym sposobem naprawy jest odesłanie numeru currentCountry w 2. wyborze i nie ma potrzeby używania numeru $watch, aby spełnić wymagania.

<select data-ng-model="currentCountry" data-ng-options="country.name for country in Countries.items"> 

<select data-ng-model="currentItem" data-ng-options="item.id as item.name for item in States.StateGroups[currentCountry.StateGroupID].items"> 

Demo

+0

Twoja odpowiedź jest dobra, ale zmieniłeś kod HTML, a konkretnie wspomniałem, że chciałbym zachować aktualny kod HTML i używać JavaScript. – Scription

+0

@spis Nie widzę tego w Twoim pytaniu. Wspomniałeś coś o strukturze danych, ale to całkowicie różni się od HTML. – zsong

0

kątowe-country-zbieracz altana zainstalować kątowe-country-kompletacji (lub) npm zainstalować kątową-Country-kompletacji

<script src="bower_components/angular-country-picker/country-picker.js"></script> 
<script src="node_modules/angular-country-picker/country-picker.js"></script> 

     angular.module('webApp', ['puigcerber.countryPicker']); 

     <select ng-model="selectedCountry" pvp-country-picker="name"></select> 

     angular.module('myApp', ['puigcerber.countryPicker']) 
     .config(function(pvpCountriesProvider) { 
     pvpCountriesProvider.setCountries([ 
     { name: 'Abkhazia', alpha2: 'AB'}, 
     { name: 'Kosovo', alpha2: 'XK'}, 
     { name: 'Nagorno-Karabakh', alpha2: 'NK'}, 
     { name: 'Northern Cyprus', alpha2: 'KK'}, 
     { name: 'Somaliland', alpha2: 'JS'}, 
     { name: 'South Ossetia', alpha2: 'XI'}, 
     { name: 'Transnistria', alpha2: 'PF'} 
     ]); 
    }); 
Powiązane problemy