2013-05-31 27 views
6

我所有的指令都使用相同的範圍,我希望我的指令能夠自己操作。如何防止範圍在指令中共享?Angular?

指令:

app.directive('headerSort', function() { 
    return { 
     restrict: 'A', 
     controller: function ($scope, $element, $attrs) { 
      $scope.caption = $attrs.caption; 

      $scope.doSort = function() { 
       $scope.orderField = $attrs.headerSort; 
       $scope.reverse = !$scope.reverse; 
      }; 
     }, 
     template: '<div data-ng-click="doSort();">' + 
        '{{caption}}' + 
        '<i class="icon-sort"></i>' + 
        '</div>' 
    }; 
}); 

HTML:

<th data-header-Sort="FullName" data-caption="Full name"></th> 
<th data-header-Sort="FirsName" data-caption="First name"></th> 
<th data-header-Sort="Age" data-caption="Age"></th> 

其結果是,所有列的值是 '年齡' 和排序年齡。我當然希望每一列都是自己的專欄。我怎樣才能做到這一點?

UPDATE: 忘了提,orderFieldreverseng-repeat | orderBy使用:

<tbody id="customerRows" data-ng-repeat="customer in customers | orderBy:orderField:reverse"> 
+0

您可能感興趣的AngularUI的ng-grid指令@ http://angular-ui.github.io/ng-grid/ –

回答

11

指令的每個實例都需要有自己的標題,排序類型和反向屬性。因此,指令將需要自己的(子)範圍—或者隔離範圍(scope: {})或新範圍(scope: true)。由於該指令不是獨立/獨立組件,因此我不會使用隔離範圍(另請參閱When writing a directive in AngularJS, how do I decide if I need no new scope, a new child scope, or a new isolated scope?)。

使用爲指令選擇的作用域類型,排序類型和反向值可以通過函數參數傳遞給父項,也可以直接在父作用域上設置。我建議函數參數:

app.directive('headerSort', function() { 
    return { 
     scope: true, // creates a new child scope 
     link: function (scope, element, attrs) { 
      scope.caption = attrs.caption; 
      scope.sortType = attrs.headerSort; 
      scope.reverse = false; 
     }, 
     template: '<div data-ng-click="reverse=!reverse; doSort(sortType, reverse);">' + 
      '{{caption}}</div>' 
    }; 
}); 
function MyCtrl($scope) { 
    $scope.orderField = "FirstName"; 
    $scope.reverse = false; 
    $scope.customers = [ {FirstName: 'Martijn', Age: 22}, {FirstName: 'Mark', Age: 44}]; 
    $scope.doSort = function (sortType, reverse) { 
     console.log('sorting',sortType, reverse); 
     $scope.orderField = sortType; 
     $scope.reverse = reverse; 
    }; 
} 
<table> 
    <th data-header-sort="FirstName" data-caption="First name"></th> 
    <th data-header-sort="Age" data-caption="Age"></th> 
    <tbody id="customerRows" data-ng-repeat="customer in customers | orderBy:orderField:reverse"> 
     <tr><td>{{customer.FirstName}}<td>{{customer.Age}} 
    </tbody> 
</table> 

fiddle在小提琴,只是爲了簡單起見,我沒有包括全名列。

+0

非常感謝!也爲鏈接和進一步解釋! – Martijn

1

你需要 「隔離」 的範圍。這將使指令的每個實例都有自己的作用域。以下內容添加到您的指令定義:

scope: {}, 

那麼,您的最終指令的定義是這樣的:

app.directive('headerSort', function() { 
    return { 
     restrict: 'A', 
     scope: {}, 
     controller: function ($scope, $element, $attrs) { 
      $scope.caption = $attrs.caption; 

      $scope.doSort = function() { 
       $scope.orderField = $attrs.headerSort; 
       $scope.reverse = !$scope.reverse; 
      }; 
     }, 
     template: '<div data-ng-click="doSort();">' + 
        '{{caption}}' + 
        '<i class="icon-sort"></i>' + 
        '</div>' 
    }; 
}); 

的Egghead.io視頻進去範圍隔離在深度。您可以在這裏查看它們:http://www.egghead.io/

隔離示波器視頻從教程#16開始。

+0

Thanx。列名沒有正確顯示,但點擊仍然無效。如果它變得更容易,我不會在doSort所在的位置丟棄它。在控制器範圍或指令的控制器範圍內。 – Martijn

+0

'$ scope.orderField'將在隔離範圍上設置一個屬性,而不是父範圍,所以這不起作用。 –

+0

你是對的馬克,你可能會更好使用子範圍。 – Polaris878