2014-04-29 153 views
2

我遇到問題了解範圍。當你使用tabset時,ui-bootstrap會創建一個新的範圍,我明白了。我認爲父方法可用於子範圍?這是一個顯示我的問題的jsbin。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

選項卡可能實現爲具有隔離範圍並且不與其他範圍構成父/子關係的指令。除此之外,似乎你已經分享了很多代碼,但我不確定是什麼問題。 – JeffryHouser

+0

你是對的Tabs是一個指令。我在這些下拉菜單中需要調用父範圍的函數。我相信這個範圍是被橫掃的。 –

回答

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重複

<li ng-repeat="s in scripts|filter:filterByName"> 

新的NG-重複

<li ng-repeat="s in filterByName(scripts, search)"> 
+0

爲什麼你使用下劃線的foreach這只是一個synomym的JavaScript foreach?你正在寫一個角度應用程序,並在角度上下文中,你不應該使用angular.foreach嗎? – mortsahl

+0

嘿mortashi,說實話?習慣。我對下劃線感到非常舒服,所以我在各地都使用它。對於這個項目我不需要支持IE8,所以我可以使用JavaScript的每一個,但在現實世界中使用這個特定的應用程序,我沒有注意到性能差異。感謝大家的支持,我不應該懶惰地按照習慣編寫代碼。 –

2

範圍是有趣和令人困惑。除$ rootScape外,所有範圍都有祖先。我不確定,但我認爲ui-bootstrap tabset創建了自己的隔離範圍。這個隔離範圍確實有一個父級,但是你已經「隔離」它,所以它不能看到祖先範圍的任何屬性,除非你已經明確地將它們包含在指令中。如果隔離範圍具有不是孤立範圍的子範圍,則它可以查看和操縱其父項屬性,但不會遠離祖先鏈。事件可以自由地上下傳遞,你應該非常小心地使用它們,因爲在處理隔離範圍時,可能會導致你不期望的副作用。

如果上面只是一堆亂七八糟的東西,請到https://docs.angularjs.org/guide/directive並重新閱讀那裏的信息 - 也許這會讓它更加清晰。

這裏大概範圍上最好的論文,你會在一個快速,簡潔和清晰的解釋測量值的一個 - What are the nuances of scope prototypal/prototypical inheritance in AngularJS?