Skip to content

Commit 7f336d4

Browse files
committed
refactor(core) ui-grid $parent scope is now automatically assigned to grid.appScope.
gridOptions.appScopeProvider can be used to assign anything to grid.appScope BREAKING CHANGE: getExternalScopes() function is removed. Use grid.appScope instead. external-scopes attribute is removed. Use gridOptions.appScopeProvider to assign values other than $scope.$parent to appScope
1 parent 35375f2 commit 7f336d4

17 files changed

+111
-87
lines changed

3.0_UPGRADE.md

+3-7
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ $scope.gridOptions = {
6060
```
6161
6262
## ui-grid uses an isolate scope
63-
You can no longer access data or functions directly on the parent scope. You can access a pre-defined scope by using getExternalScopes(), and set this scope using the external-scopes directive.
63+
You can no longer access data or functions directly on the parent scope. You must use grid.appScope to get a reference to the parent scope
6464
6565
Before:
6666
```javascript
@@ -85,7 +85,7 @@ After:
8585
$scope.gridScope = $scope;
8686
$scope.gridOptions = {
8787
columnDefs = [
88-
{ name: 'edit', displayName: 'Edit', cellTemplate: '<button ng-click="getExternalScopes().edit(row.entity)" >Edit</button>' }
88+
{ name: 'edit', displayName: 'Edit', cellTemplate: '<button ng-click="grid.appScope.edit(row.entity)" >Edit</button>' }
8989
],
9090
data: myData
9191
};
@@ -95,15 +95,11 @@ $scope.edit = function( entity ) {
9595
};
9696
```
9797

98-
```html
99-
<div ui-grid="gridOptions" external-scopes="gridScope" ></div>
100-
```
101-
10298
## Some features previously included in the base are now plugins.
10399

104100
Refer to the tutorials and API documentation at http://ui-grid.info/docs/ for more detail, an example provided below is column resizing. The plugins are available in the base javascript, using them requires only including the appropriate directive in the grid declaration:
105101

106102
After:
107103
```html
108-
<div ui-grid="gridOptions" external-scopes="gridScope" ui-grid-resize-columns ></div>
104+
<div ui-grid="gridOptions" ui-grid-resize-columns ></div>
109105
```

misc/tutorial/099_upgrading_from_2.ngdoc

+4-17
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ $scope.gridOptions.columnDefs = [...];
8888
In 2.x you would use `row.getProperty(col.field)` within a cellTemplate to get the value of a cell. In 3.0 this has changed to `grid.getCellValue(row, col)`.
8989

9090

91-
### External scopes must be declared ###
91+
### Grid now uses isolate scope ###
9292
The grid now uses an isolate scope, meaning that the scope on your controller is not directly accessible
93-
to widgets that you include in the grid. You now need to declare an external scope (refer associated tutorial).
93+
to widgets that you include in the grid. You can get the parent scope used by the ui-grid element in any template
94+
with the grid.appScope property. {{grid.appScope}}
9495

9596
<pre>
9697
$scope.gridOptions = {
@@ -108,25 +109,11 @@ $scope.gridOptions = {
108109
columnDefs: [
109110
{field: 'id', displayName: 'Id'},
110111
{field: 'name', displayName: 'Name'},
111-
{name: 'edit', displayName: 'Edit', cellTemplate: '<button id="editBtn" type="button" class="btn-small" ng-click="getExternalScopes().edit(row.entity)" >Edit</button> '}
112+
{name: 'edit', displayName: 'Edit', cellTemplate: '<button id="editBtn" type="button" class="btn-small" ng-click="grid.appScope.edit(row.entity)" >Edit</button> '}
112113
]
113114
};
114115
</pre>
115116

116-
You also need to declare the external scope within your controller:
117-
<pre>
118-
$scope.myScope = {
119-
edit: function( row ) {
120-
// do something
121-
}
122-
};
123-
</pre>
124-
125-
And on the grid directive:
126-
<pre>
127-
<div class="gridStyle" ui-grid="gridOptions" external-scopes="myScope" ></div>
128-
</pre>
129-
130117

131118
### Separate features ###
132119
Many elements included by default in ng-grid have now been shifted into separate features, allowing the

misc/tutorial/301_custom_row_template.ngdoc

+7-14
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44

55
Create a grid almost the same as the most basic one, but with a custom row template.
66

7-
You can use [external scopes](/docs/#/tutorial/305_externalScopes) in your row template to access
8-
elements in your controller's scope. The `external-scopes` attribute on the grid will expose the
9-
property on your `$scope` with that name in the grid's isolate scope. You can then
10-
use `getExternalScopes()` in your row template to access that. More details are on
11-
the [external scopes](/docs/#/tutorial/305_externalScopes) tutorial.
7+
You can use [grid.appScope](/docs/#/tutorial/305_appScope) in your row template to access
8+
elements in your controller's scope. More details are on
9+
the [external scopes](/docs/#/tutorial/305_appScope) tutorial.
1210

1311
@example
1412
<example module="app">
@@ -27,17 +25,14 @@ the [external scopes](/docs/#/tutorial/305_externalScopes) tutorial.
2725
$scope.waiting = 'Done!';
2826
$interval.cancel(sec);
2927
$scope.wait = '';
30-
// Calling the externalScopes() method will allow you to reach up to the controller scope
31-
return '<div style="background-color: aquamarine" ng-click="getExternalScopes().fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ui-grid-cell></div>';
28+
return '<div style="background-color: aquamarine" ng-click="grid.appScope.fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ui-grid-cell></div>';
3229
}, 6000);
3330
}
3431

3532
// Access outside scope functions from row template
36-
$scope.myNewModel = {
37-
fnOne: function(row) {
33+
$scope.fnOne = function(row) {
3834
console.log(row);
39-
}
40-
};
35+
};
4136

4237
$scope.waiting = 'Waiting for row template...';
4338

@@ -56,9 +51,7 @@ the [external scopes](/docs/#/tutorial/305_externalScopes) tutorial.
5651
<div ng-controller="MainCtrl">
5752
<strong ng-bind="waiting"></strong> <strong>{{ wait }}</strong>
5853
<br>
59-
<br>
60-
//make sure to set the controller variable in the attribute like so:
61-
<div class="grid" ui-grid="gridOptions" external-scopes="myNewModel"></div>
54+
<div class="grid" ui-grid="gridOptions" ></div>
6255
</div>
6356
</file>
6457
<file name="main.css">

misc/tutorial/305_externalScopes.ngdoc misc/tutorial/305_appScope.ngdoc

+22-19
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
@ngdoc overview
2-
@name Tutorial: 305 External Scopes
2+
@name Tutorial: 305 Accessing Scope in templates
33
@description
44

55
UI-Grid uses isolate scope, so there is no access to your application scope variables from a row or cell template.
6-
7-
To access your application data within UI-Grid, use the external-scopes attribute. Give the attribute a
8-
property that exists on your scope.
9-
<pre>
10-
$scope.myViewModel.showMe = function(){...};
11-
<div ui-grid="{ data: myData }" external-scopes="myViewModel" class="grid"></div>
12-
</pre>
13-
14-
Then in a template, you access the scope using getExternalScopes() function.
6+
By default, the parent scope of the ui-grid element is assigned to a property on $scope.grid named appScope.
7+
<br/>
8+
<br/>
9+
If you need another reference other than $scope.$parent, then use gridOptions.appScopeProvider. This reference
10+
will be assigned to grid.appScope.
11+
<br/>
12+
<br/>
13+
$scope.grid.appScope is available in all templates that the grid uses.
14+
<br/>
15+
In a template, you access the scope using grid.appScope property
1516
<pre>
16-
ng-click="getExternalScopes().showMe()"
17+
ng-click="grid.appScope.showMe()"
1718
</pre>
1819

1920
@example
@@ -23,20 +24,22 @@ Then in a template, you access the scope using getExternalScopes() function.
2324

2425
app.controller('MainCtrl', ['$scope', '$log', '$http', function ($scope, $log, $http) {
2526

26-
$scope.myViewModel = {
27-
someProp:'abc',
28-
showMe : function(){
29-
alert(this.someProp);
30-
}
31-
};
27+
28+
$scope.someProp = 'abc',
29+
$scope.showMe = function(){
30+
alert($scope.someProp);
31+
};
3232

3333
$scope.gridOptions = {};
3434

35+
//you can override the default assignment if you wish
36+
//$scope.gridOptions.appScopeProvider = someOtherReference;
37+
3538
$scope.gridOptions.columnDefs = [
3639
{ name: 'name' },
3740
{ name: 'gender'},
3841
{ name: 'ShowScope',
39-
cellTemplate:'<button class="btn primary" ng-click="getExternalScopes().showMe()">Click Me</button>' }
42+
cellTemplate:'<button class="btn primary" ng-click="grid.appScope.showMe()">Click Me</button>' }
4043
];
4144
/*
4245
$scope.gridOptions.data = [
@@ -70,7 +73,7 @@ Then in a template, you access the scope using getExternalScopes() function.
7073
</file>
7174
<file name="index.html">
7275
<div ng-controller="MainCtrl">
73-
<div ui-grid="gridOptions" external-scopes="myViewModel" class="grid"></div>
76+
<div ui-grid="gridOptions" class="grid"></div>
7477
</div>
7578
</file>
7679
<file name="main.css">

src/js/core/directives/ui-grid-footer-cell.js

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
post: function ($scope, $elm, $attrs, uiGridCtrl) {
2222
//$elm.addClass($scope.col.getColClass(false));
2323
$scope.grid = uiGridCtrl.grid;
24-
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;
2524

2625
$elm.addClass($scope.col.getColClass(false));
2726

src/js/core/directives/ui-grid-footer.js

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
$scope.grid = uiGridCtrl.grid;
2020
$scope.colContainer = containerCtrl.colContainer;
21-
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;
2221

2322
containerCtrl.footer = $elm;
2423

src/js/core/directives/ui-grid-grid-footer.js

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
pre: function ($scope, $elm, $attrs, uiGridCtrl) {
1616

1717
$scope.grid = uiGridCtrl.grid;
18-
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;
1918

2019
var footerTemplate = ($scope.grid.options.gridFooterTemplate) ? $scope.grid.options.gridFooterTemplate : defaultTemplate;
2120
gridUtil.getTemplate(footerTemplate)

src/js/core/directives/ui-grid-header-cell.js

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
var renderContainerCtrl = controllers[1];
2828

2929
$scope.grid = uiGridCtrl.grid;
30-
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;
3130

3231
$scope.renderContainer = uiGridCtrl.grid.renderContainers[renderContainerCtrl.containerId];
3332

src/js/core/directives/ui-grid-header.js

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
$scope.grid = uiGridCtrl.grid;
2222
$scope.colContainer = containerCtrl.colContainer;
23-
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;
2423

2524

2625

src/js/core/directives/ui-grid-row.js

-5
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,7 @@
6060
});
6161
},
6262
post: function($scope, $elm, $attrs, controllers) {
63-
var uiGridCtrl = controllers[0];
64-
var containerCtrl = controllers[1];
6563

66-
// Sdd optional reference to externalScopes function to scope
67-
// so it can be retrieved in lower elements
68-
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;
6964
}
7065
};
7166
}

src/js/core/directives/ui-grid.js

+5-9
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@
99

1010
var self = this;
1111

12-
// Extend options with ui-grid attribute reference
1312
self.grid = gridClassFactory.createGrid($scope.uiGrid);
13+
14+
//assign $scope.$parent if appScope not already assigned
15+
self.grid.appScope = self.grid.appScope || $scope.$parent;
16+
1417
$elm.addClass('grid' + self.grid.id);
1518
self.grid.rtl = gridUtil.getStyles($elm[0])['direction'] === 'rtl';
1619

1720

18-
//add optional reference to externalScopes function to controller
19-
//so it can be retrieved in lower elements that have isolate scope
20-
self.getExternalScopes = $scope.getExternalScopes;
21-
2221
// angular.extend(self.grid.options, );
2322

2423
//all properties of grid are available on scope
@@ -139,8 +138,6 @@
139138
* @element div
140139
* @restrict EA
141140
* @param {Object} uiGrid Options for the grid to use
142-
* @param {Object=} external-scopes Add external-scopes='someScopeObjectYouNeed' attribute so you can access
143-
* your scopes from within any custom templatedirective. You access by $scope.getExternalScopes() function
144141
*
145142
* @description Create a very basic grid.
146143
*
@@ -180,8 +177,7 @@ angular.module('ui.grid').directive('uiGrid',
180177
return {
181178
templateUrl: 'ui-grid/ui-grid',
182179
scope: {
183-
uiGrid: '=',
184-
getExternalScopes: '&?externalScopes' //optional functionwrapper around any needed external scope instances
180+
uiGrid: '='
185181
},
186182
replace: true,
187183
transclude: true,

src/js/core/factories/Grid.js

+10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ angular.module('ui.grid')
3535

3636
// Get default options
3737
self.options = GridOptions.initialize( options );
38+
39+
/**
40+
* @ngdoc object
41+
* @name appScope
42+
* @propertyOf ui.grid.class:Grid
43+
* @description reference to the application scope (the parent scope of the ui-grid element). Assigned in ui-grid controller
44+
* <br/>
45+
* use gridOptions.appScopeProvider to override the default assignment of $scope.$parent with any reference
46+
*/
47+
self.appScope = self.options.appScopeProvider;
3848

3949
self.headerHeight = self.options.headerRowHeight;
4050

src/js/core/factories/GridOptions.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,20 @@ angular.module('ui.grid')
400400
* custom row template. Can be set to either the name of a template file:
401401
* <pre> $scope.gridOptions.rowTemplate = 'row_template.html';</pre>
402402
* inline html
403-
* <pre> $scope.gridOptions.rowTemplate = '<div style="background-color: aquamarine" ng-click="getExternalScopes().fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ui-grid-cell></div>';</pre>
403+
* <pre> $scope.gridOptions.rowTemplate = '<div style="background-color: aquamarine" ng-click="grid.appScope.fnOne(row)" ng-repeat="col in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ui-grid-cell></div>';</pre>
404404
* or the id of a precompiled template (TBD how to use this) can be provided.
405405
* </br>Refer to the custom row template tutorial for more information.
406406
*/
407407
baseOptions.rowTemplate = baseOptions.rowTemplate || 'ui-grid/ui-grid-row';
408+
409+
/**
410+
* @ngdoc object
411+
* @name appScopeProvider
412+
* @propertyOf ui.grid.class:GridOptions
413+
* @description by default, the parent scope of the ui-grid element will be assigned to grid.appScope
414+
* this property allows you to assign any reference you want to grid.appScope
415+
*/
416+
baseOptions.appScopeProvider = baseOptions.appScopeProvider || null;
408417

409418
return baseOptions;
410419
}

test/unit/core/directives/ui-grid-footer-cell.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ describe('uiGridFooterCell', function () {
4040
$scope.extScope = 'test';
4141

4242
recompile = function () {
43-
grid = angular.element('<div style="width: 500px; height: 300px" ui-grid="gridOpts" external-scopes="extScope"></div>');
43+
grid = angular.element('<div style="width: 500px; height: 300px" ui-grid="gridOpts"></div>');
4444

4545
$compile(grid)($scope);
4646
$document[0].body.appendChild(grid[0]);
@@ -82,8 +82,8 @@ describe('uiGridFooterCell', function () {
8282

8383
var header = $(grid).find('.ui-grid-header-cell:nth(0)');
8484
expect(header).toBeDefined();
85-
expect(header.scope().getExternalScopes).toBeDefined();
86-
expect(header.scope().getExternalScopes()).toBe('test');
85+
expect(header.scope().grid.appScope).toBeDefined();
86+
expect(header.scope().grid.appScope.extScope).toBe('test');
8787
});
8888
});
8989
});

test/unit/core/directives/ui-grid-header-cell.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('uiGridHeaderCell', function () {
5858
$scope.extScope = 'test';
5959

6060
recompile = function () {
61-
grid = angular.element('<div style="width: 500px; height: 300px" ui-grid="gridOpts" external-scopes="extScope"></div>');
61+
grid = angular.element('<div style="width: 500px; height: 300px" ui-grid="gridOpts"></div>');
6262

6363
$compile(grid)($scope);
6464
$document[0].body.appendChild(grid[0]);
@@ -194,8 +194,8 @@ describe('uiGridHeaderCell', function () {
194194

195195
var header = $(grid).find('.ui-grid-header-cell:nth(0)');
196196
expect(header).toBeDefined();
197-
expect(header.scope().getExternalScopes).toBeDefined();
198-
expect(header.scope().getExternalScopes()).toBe('test');
197+
expect(header.scope().grid.appScope).toBeDefined();
198+
expect(header.scope().grid.appScope.extScope).toBe('test');
199199
});
200200
});
201201

0 commit comments

Comments
 (0)