我在我的应用的“索引”页面上使用AngularUI Typeahead。我没有做任何花哨的事 - 事实上,我只是试图让他们在他们的UI网站上工作的例子,我收到了这个错误:
Error: Template must have exactly one root element
我不知道这意味着什么,但只有在我有以下代码时才会发生:
<input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue">
如果相关,我的主页面的控制器(通过$routeProvider
为/
索引目录调用):
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'];
}
请注意,页面上控制器的其余部分工作正常,只是导致问题的$scope.selected/$scope.states
。我无法弄清楚错误的含义,因此排除故障非常困难!
有什么想法吗?
编辑以下是我的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>
它与typeahead
脚本完全相关,我可以删除typeahead="state for state in states | filter:$viewValue"
并且脚本有效(尽管显然typeahead
函数没有......)
答案 0 :(得分:22)
确保添加正确的ui-bootstrap-tpls-[version].min.js
文件(tpls版本包含模板和代码)。您将需要一个引用本地或cdn版本的脚本标记。
这个错误最有可能是由于角度无法找到模板来显示预先输入选项,尝试通过http获取一个而不是检索404(使用新的根html元素,因此错误)
答案 1 :(得分:2)
我遇到了同样的问题,但是使用ui-select指令但是一般问题都是一样的。
我终于可以解决我的问题而且我可以确定在我的情况下问题是我添加了一个http拦截器来自动添加所有http请求令牌返回服务器。
但是,在内部进程检查模板缓存之前添加了令牌,结果是我的拦截器(bootstrap.select.tpl.html?)更改了所请求的文件(bootstrap.select.tpl.html)?令牌= xxxxxx)并且它不再是高速缓存中所知,服务器就喜欢从服务器下载它。但是在服务器上我无法解析网址请求,我回答了默认网页。
我确实修改了拦截器以检查请求的URL是否已经在缓存中,并且只有在缓存中找不到页面时才添加令牌。之后一切都运行良好。
希望有人能从这样的解决方案中受益
/**
* 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);
}
};
}
);
}
);
答案 2 :(得分:1)
您的indexCtrl
未在您的html(ng-controller)中引用。您不应该使用未定义的使用$scope.selected = '';
来初始化您选择的变量,或者只是删除它。
这段代码正在运行:
<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'];
});
答案 3 :(得分:0)
您还需要将模板文件包装在一个元素中(包括注释)。阅读更多here
答案 4 :(得分:0)
遇到山姆问题,发现了我的错误。 我已删除所有模板缓存,这将导致所有模板无法正常工作