2013-07-15 8 views
6

Używam AngularUI Typeahead, na stronie "indeksu" mojej aplikacji. Nie robię niczego wyjątkowego - w rzeczywistości, po prostu próbuję uzyskać przykład Mają się na ich miejscu pracy UI, a ja dostaję ten błąd:AngularJS - "Błąd: szablon musi mieć dokładnie jeden element główny" podczas używania Angular-UI Typeahead

Error: Template must have exactly one root element 

nie mam pojęcia co to znaczy, ale to zdarza się tylko gdy mam następujący kod:

<input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue"> 

razie potrzeby, mój sterownik do mojej stronie głównej (która jest wywoływana przez $routeProvider do katalogu / index):

function indexCtrl($scope, $location, $resource) { 
    $scope.selected = undefined; 
    $scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']; 

} 

Należy zauważyć, że reszta kontrolera na stronie działa absolutnie dobrze, to tylko błąd $scope.selected/$scope.states. Nie mogę zrozumieć, co oznacza błąd, więc rozwiązywanie problemów jest dość trudne!

Wszelkie pomysły?

EDIT Oto mój szablon HTML:

<html ng-app="myApp" class="ng-scope"> 
    <head> 
    // Head stuff, probably irrelevant 
    </head> 
    <body> 
    <div class="container"> 
     <div ng-view="" class="row-fluid"> 
      <form class="row-fluid"> 
       <div class="container-fluid"> 
        <input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue"> 
       </div> 
      </form> 
     </div> 
    </div> 
// A bunch of Angular scripts are here 
    </body> 
    </html> 

to z pewnością związane ot skrypt typeahead mogę usunąć typeahead="state for state in states | filter:$viewValue" i działa skrypt (choć oczywiście funkcja typeahead nie robi ...)

+1

Co jest 'wejściowy (type = "text", ng model = "wybrany", wpisywanie znaków z wyprzedzeniem = "stan do stanu, w stanach | filtra: $ viewValue") ', czy nie jest to' '? –

+0

@YeLiu Och, przepraszam, to część silnika szablonowego 'Jade' używanego przez ExpressJS. Przedstawia się tak, jak powiedziałeś, zaktualizuję pytanie, aby to odzwierciedlić. – Jascination

+0

Umieść swój html/szablon, ponieważ błąd dotyczy szablonu. –

Odpowiedz

1

Twój numer indexCtrl nie jest wymieniony w twoim html (ng-controller). Nie powinieneś inicjować wybranej zmiennej z nieokreślonym użyciem, zamiast tego, lub usuń ją. Ten kod działa:

<div class="container"> 
    <div ng-controller="mainCtrl" class="row-fluid"> 
     <form class="row-fluid"> 
      <div class="container-fluid"> 
       <input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue"> 
      </div> 
     </form> 
    </div> 
</div> 

angular.module('myApp', ['ui.bootstrap']) 
    .controller("mainCtrl", function ($scope) { 
    $scope.selected = ''; 
    $scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']; 
}); 

JSFiddle: http://jsfiddle.net/alfrescian/EDZgT/

22

Upewnij się, dodając odpowiednią ui-bootstrap-tpls-[version].min.js plik (tpls wersje zawierają szablony, jak również kod). Będziesz potrzebował tagu skryptu gdzieś odwołującego się do wersji lokalnej lub cdn.

Jest to najprawdopodobniej spowodowane tym, że ten kąt jest spowodowany przez brak możliwości znalezienia szablonu, który wyświetli opcje głowicy, próbując pobrać go przez HTTP i pobierając 404 (z nowym elementem html root, co powoduje błąd).

+6

Upewnij się, że umieściłeś "ui.bootstrap.tpls" jako część swojego modułu kątowego! – mattwad

+3

Dołącz także znacznik skryptu 'kątowy-bootstrap.js' przed tagiem' ui-bootstrap-tpls.js' –

+0

Dzięki mnie zadziałało – MNR

0

również musisz zawinąć plik szablonu w jeden element (w tym komentarze). przeczytaj więcej here

0

spotkać sam problem i znalazłem mój błąd. Mam usunąćWszystko templateCache, które doprowadzi wszystkich szablon nie działa

2

Miałem ten sam problem, ale z dyrektywą ui-select, ale ogólny problem byłby taki sam.

Mogłem w końcu rozwiązać mój problem i mogłem stwierdzić, że w moim przypadku problem polegał na tym, że dodałem przechwytywacz HTTP, aby dodać automatyczne do wszystkich żądań http tokena z powrotem na serwer.

Ale gdy token został dodany, zanim wewnętrzny proces mógł sprawdzić pamięć podręczną szablonów, to skończyło się, że żądany plik (bootstrap.select.tpl.html) został zmieniony przez mój przechwytujący (bootstrap.select.tpl.html ?token = xxxxxx) i nie było już wiadomo w hachu pamięci podręcznej, a serwer lubił pobierać go z serwera. Ale na serwerze nie mogłem rozwiązać żądania adresu URL i odpowiadam na domyślną stronę.

Zmodyfikowałem mój przechwytujący, aby sprawdzić, czy żądany adres URL nie znajduje się już w pamięci podręcznej i dodać token, jeśli strona nie została znaleziona w pamięci podręcznej. Po tym wszystkim wszystko działało dobrze.

nadzieję, że ktoś może skorzystać z takiego rozwiązania

/** 
* Intercept all http-Traffic to add the token 
*/ 
app.config(
    function ($httpProvider) { 
    $httpProvider.interceptors.push(function ($q, $rootScope, $localStore, $templateCache) { 
     return { 
      request: function (config) { 
      // check if the cache has the file already loaded, in this case do not append any token 
      if (!$templateCache.get(config.url)) { 
       if (!config.params) config.params = {}; 
       var token = $rootScope.token; 
       if (token !== null && token !== undefined && token !== 'undefined') { 
       $localStore.set('token', token); 
       // only if it's a valid token, add it 
       config.params.token = token; 
       } 
      } 
      return config || $q.when(config); 
      } 
     }; 
     } 
    ); 
    } 
); 
+0

W moim przypadku był to cache-cust-buster. – Thomas

Powiązane problemy