我在理解范围方面遇到了问题。当你使用tabset时,ui-bootstrap会创建一个新的范围,我明白了。我认为父方法可用于子范围?这是一个显示我的问题的jsbin。
我确定有一些简单的东西我没有丢失,但是我无法看到它。
代码内联以防JSBin起作用:
angular.module('app', ['ui.bootstrap'])
.controller('MainController', function($scope) {
$scope.filters = [];
$scope.search = '';
$scope.providerVersions = [
{ name:'SomeOS', type:'pv' },
{ name:'OtherOS', type:'pv' }
];
$scope.scripts = [
{ name:'Something', pv:'SomeOS', type:'script' },
{ name:'Somebody', pv:'SomeOS', type:'script' },
{ name:'Other thing', pv:'OtherOS', type:'script' },
{ name:'Other body', pv:'OtherOS', type:'script' }
];
$scope.addFilter = function(f) {
$scope.filters.push({ name:f.name, type:f.type });
};
$scope.remFilter = function(i) {
$scope.filters.splice(i,1);
};
$scope.filterByName = function(n) {
var name = n.name.toLowerCase();
var search = $scope.search.toLowerCase();
return name.indexOf(search) > -1;
};
$scope.filterByFilters = function(f) {
if ($scope.filters.length===0) { return true; }
var byName = _.where($scope.filters, { type:'script' });
if (byName.length > 0) {
return _.contains(_.pluck(byName, 'name'), f.name);
}
return _.contains(_.pluck($scope.filters, 'name'), f.pv);
};
});
HTML
<body ng-app="app">
<div ng-controller="MainController">
<h3>This works</h3>
<p>Filters on both name and role as expected.</p>
<div ng-repeat="s in scripts|filter:filterByFilters">
{{ s.name }}
</div>
<form name="searchForm">
<input type="text" class="form-control" placeholder="Filter by name or role" ng-model="search">
</form>
<span ng-repeat="f in filters"><a ng-click="remFilter($index)">{{ f.name }}</a><span ng-if="!$last">, </span></span>
<ul ng-show="search.length>0" class="dropdown-menu" style="display:block; position:static;">
<li class="dropdown-header">Name</li>
<li ng-repeat="s in scripts|filter:filterByName"><a ng-click="addFilter(s)">{{ s.name }}</a></li>
<li class="divider"></li>
<li class="dropdown-header">Role</li>
<li ng-repeat="p in providerVersions|filter:search"><a ng-click="addFilter(p)">{{ p.name }}</a></li>
</ul>
<h3>This does not work</h3>
<p>Only filters on role. It does not call $scope.filterByName.</p>
<tabset>
<tab heading="Scripts">
<div ng-repeat="s in scripts|filter:filterByFilters">
{{ s.name }}
</div>
<form name="searchForm">
<input type="text" class="form-control" placeholder="Filter by name or role" ng-model="search">
</form>
<span ng-repeat="f in filters"><a ng-click="remFilter($index)">{{ f.name }}</a><span ng-if="!$last">, </span></span>
<ul ng-show="search.length>0" class="dropdown-menu" style="display:block; position:static;">
<li class="dropdown-header">Name</li>
<li ng-repeat="s in scripts|filter:filterByName"><a ng-click="addFilter(s)">{{ s.name }}</a></li>
<li class="divider"></li>
<li class="dropdown-header">Role</li>
<li ng-repeat="p in providerVersions|filter:search"><a ng-click="addFilter(p)">{{ p.name }}</a></li>
</ul>
</tab>
</tabset>
</div>
</body>
答案 0 :(得分:2)
范围很有趣且令人困惑。除$ rootScape之外的所有范围都有祖先。我不确定,但我认为ui-bootstrap tabset创建了自己的隔离范围。隔离范围确实有父母,但你已经隔离了&#34;因此它无法看到祖先范围的任何属性,除非您在指令中明确包含它们。如果隔离范围的子范围不是隔离范围,它可以查看和操纵其父项属性,但不能追溯到祖先链的后面。事件可以自由地在链中上下传递,你应该非常小心地使用它们,因为在处理隔离范围时,可能会引起你不期望的副作用。
如果以上只是一堆喋喋不休,请转到https://docs.angularjs.org/guide/directive并重读那里的信息 - 也许这会让它更清晰。
这里可能是关于范围的最佳论文之一,您将以快速,简洁和清晰的解释 - What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
答案 1 :(得分:0)
我能够解决这个问题。老实说,我不知道为什么会这样,但确实如此。也许其他人可以为我填补空白。我所做的不是尝试过滤我的列表,而是更改了过滤器函数以返回一个数组,并使用该结果进行ng-repeat迭代。
旧过滤功能
$scope.filterByName = function(n) {
var name = n.name.toLowerCase();
var search = $scope.search.toLowerCase();
return name.indexOf(search) > -1;
};
新过滤功能
$scope.filterByName = function(list, srch) {
var ret = [];
_.each(list, function(l) {
if (l.name.toLowerCase().indexOf(srch.toLowerCase()) > -1) {
ret.push(l);
}
});
return ret;
};
旧ng-repeat
<li ng-repeat="s in scripts|filter:filterByName">
新ng-repeat
<li ng-repeat="s in filterByName(scripts, search)">