Skip to content

Commit

Permalink
refactor(core) ui-grid $parent scope is now automatically assigned to…
Browse files Browse the repository at this point in the history
… 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
  • Loading branch information
swalters committed Jan 21, 2015
1 parent 35375f2 commit 7f336d4
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 87 deletions.
10 changes: 3 additions & 7 deletions 3.0_UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ $scope.gridOptions = {
```
## ui-grid uses an isolate scope
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.
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
Before:
```javascript
Expand All @@ -85,7 +85,7 @@ After:
$scope.gridScope = $scope;
$scope.gridOptions = {
columnDefs = [
{ name: 'edit', displayName: 'Edit', cellTemplate: '<button ng-click="getExternalScopes().edit(row.entity)" >Edit</button>' }
{ name: 'edit', displayName: 'Edit', cellTemplate: '<button ng-click="grid.appScope.edit(row.entity)" >Edit</button>' }
],
data: myData
};
Expand All @@ -95,15 +95,11 @@ $scope.edit = function( entity ) {
};
```

```html
<div ui-grid="gridOptions" external-scopes="gridScope" ></div>
```

## Some features previously included in the base are now plugins.

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:

After:
```html
<div ui-grid="gridOptions" external-scopes="gridScope" ui-grid-resize-columns ></div>
<div ui-grid="gridOptions" ui-grid-resize-columns ></div>
```
21 changes: 4 additions & 17 deletions misc/tutorial/099_upgrading_from_2.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,10 @@ $scope.gridOptions.columnDefs = [...];
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)`.


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

<pre>
$scope.gridOptions = {
Expand All @@ -108,25 +109,11 @@ $scope.gridOptions = {
columnDefs: [
{field: 'id', displayName: 'Id'},
{field: 'name', displayName: 'Name'},
{name: 'edit', displayName: 'Edit', cellTemplate: '<button id="editBtn" type="button" class="btn-small" ng-click="getExternalScopes().edit(row.entity)" >Edit</button> '}
{name: 'edit', displayName: 'Edit', cellTemplate: '<button id="editBtn" type="button" class="btn-small" ng-click="grid.appScope.edit(row.entity)" >Edit</button> '}
]
};
</pre>

You also need to declare the external scope within your controller:
<pre>
$scope.myScope = {
edit: function( row ) {
// do something
}
};
</pre>

And on the grid directive:
<pre>
<div class="gridStyle" ui-grid="gridOptions" external-scopes="myScope" ></div>
</pre>


### Separate features ###
Many elements included by default in ng-grid have now been shifted into separate features, allowing the
Expand Down
21 changes: 7 additions & 14 deletions misc/tutorial/301_custom_row_template.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@

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

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

@example
<example module="app">
Expand All @@ -27,17 +25,14 @@ the [external scopes](/docs/#/tutorial/305_externalScopes) tutorial.
$scope.waiting = 'Done!';
$interval.cancel(sec);
$scope.wait = '';
// Calling the externalScopes() method will allow you to reach up to the controller scope
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>';
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>';
}, 6000);
}

// Access outside scope functions from row template
$scope.myNewModel = {
fnOne: function(row) {
$scope.fnOne = function(row) {
console.log(row);
}
};
};

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

Expand All @@ -56,9 +51,7 @@ the [external scopes](/docs/#/tutorial/305_externalScopes) tutorial.
<div ng-controller="MainCtrl">
<strong ng-bind="waiting"></strong> <strong>{{ wait }}</strong>
<br>
<br>
//make sure to set the controller variable in the attribute like so:
<div class="grid" ui-grid="gridOptions" external-scopes="myNewModel"></div>
<div class="grid" ui-grid="gridOptions" ></div>
</div>
</file>
<file name="main.css">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
@ngdoc overview
@name Tutorial: 305 External Scopes
@name Tutorial: 305 Accessing Scope in templates
@description

UI-Grid uses isolate scope, so there is no access to your application scope variables from a row or cell template.

To access your application data within UI-Grid, use the external-scopes attribute. Give the attribute a
property that exists on your scope.
<pre>
$scope.myViewModel.showMe = function(){...};
<div ui-grid="{ data: myData }" external-scopes="myViewModel" class="grid"></div>
</pre>

Then in a template, you access the scope using getExternalScopes() function.
By default, the parent scope of the ui-grid element is assigned to a property on $scope.grid named appScope.
<br/>
<br/>
If you need another reference other than $scope.$parent, then use gridOptions.appScopeProvider. This reference
will be assigned to grid.appScope.
<br/>
<br/>
$scope.grid.appScope is available in all templates that the grid uses.
<br/>
In a template, you access the scope using grid.appScope property
<pre>
ng-click="getExternalScopes().showMe()"
ng-click="grid.appScope.showMe()"
</pre>

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

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

$scope.myViewModel = {
someProp:'abc',
showMe : function(){
alert(this.someProp);
}
};

$scope.someProp = 'abc',
$scope.showMe = function(){
alert($scope.someProp);
};

$scope.gridOptions = {};

//you can override the default assignment if you wish
//$scope.gridOptions.appScopeProvider = someOtherReference;

$scope.gridOptions.columnDefs = [
{ name: 'name' },
{ name: 'gender'},
{ name: 'ShowScope',
cellTemplate:'<button class="btn primary" ng-click="getExternalScopes().showMe()">Click Me</button>' }
cellTemplate:'<button class="btn primary" ng-click="grid.appScope.showMe()">Click Me</button>' }
];
/*
$scope.gridOptions.data = [
Expand Down Expand Up @@ -70,7 +73,7 @@ Then in a template, you access the scope using getExternalScopes() function.
</file>
<file name="index.html">
<div ng-controller="MainCtrl">
<div ui-grid="gridOptions" external-scopes="myViewModel" class="grid"></div>
<div ui-grid="gridOptions" class="grid"></div>
</div>
</file>
<file name="main.css">
Expand Down
1 change: 0 additions & 1 deletion src/js/core/directives/ui-grid-footer-cell.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
post: function ($scope, $elm, $attrs, uiGridCtrl) {
//$elm.addClass($scope.col.getColClass(false));
$scope.grid = uiGridCtrl.grid;
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;

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

Expand Down
1 change: 0 additions & 1 deletion src/js/core/directives/ui-grid-footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

$scope.grid = uiGridCtrl.grid;
$scope.colContainer = containerCtrl.colContainer;
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;

containerCtrl.footer = $elm;

Expand Down
1 change: 0 additions & 1 deletion src/js/core/directives/ui-grid-grid-footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
pre: function ($scope, $elm, $attrs, uiGridCtrl) {

$scope.grid = uiGridCtrl.grid;
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;

var footerTemplate = ($scope.grid.options.gridFooterTemplate) ? $scope.grid.options.gridFooterTemplate : defaultTemplate;
gridUtil.getTemplate(footerTemplate)
Expand Down
1 change: 0 additions & 1 deletion src/js/core/directives/ui-grid-header-cell.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
var renderContainerCtrl = controllers[1];

$scope.grid = uiGridCtrl.grid;
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;

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

Expand Down
1 change: 0 additions & 1 deletion src/js/core/directives/ui-grid-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

$scope.grid = uiGridCtrl.grid;
$scope.colContainer = containerCtrl.colContainer;
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;



Expand Down
5 changes: 0 additions & 5 deletions src/js/core/directives/ui-grid-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,7 @@
});
},
post: function($scope, $elm, $attrs, controllers) {
var uiGridCtrl = controllers[0];
var containerCtrl = controllers[1];

// Sdd optional reference to externalScopes function to scope
// so it can be retrieved in lower elements
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;
}
};
}
Expand Down
14 changes: 5 additions & 9 deletions src/js/core/directives/ui-grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@

var self = this;

// Extend options with ui-grid attribute reference
self.grid = gridClassFactory.createGrid($scope.uiGrid);

//assign $scope.$parent if appScope not already assigned
self.grid.appScope = self.grid.appScope || $scope.$parent;

$elm.addClass('grid' + self.grid.id);
self.grid.rtl = gridUtil.getStyles($elm[0])['direction'] === 'rtl';


//add optional reference to externalScopes function to controller
//so it can be retrieved in lower elements that have isolate scope
self.getExternalScopes = $scope.getExternalScopes;

// angular.extend(self.grid.options, );

//all properties of grid are available on scope
Expand Down Expand Up @@ -139,8 +138,6 @@
* @element div
* @restrict EA
* @param {Object} uiGrid Options for the grid to use
* @param {Object=} external-scopes Add external-scopes='someScopeObjectYouNeed' attribute so you can access
* your scopes from within any custom templatedirective. You access by $scope.getExternalScopes() function
*
* @description Create a very basic grid.
*
Expand Down Expand Up @@ -180,8 +177,7 @@ angular.module('ui.grid').directive('uiGrid',
return {
templateUrl: 'ui-grid/ui-grid',
scope: {
uiGrid: '=',
getExternalScopes: '&?externalScopes' //optional functionwrapper around any needed external scope instances
uiGrid: '='
},
replace: true,
transclude: true,
Expand Down
10 changes: 10 additions & 0 deletions src/js/core/factories/Grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ angular.module('ui.grid')

// Get default options
self.options = GridOptions.initialize( options );

/**
* @ngdoc object
* @name appScope
* @propertyOf ui.grid.class:Grid
* @description reference to the application scope (the parent scope of the ui-grid element). Assigned in ui-grid controller
* <br/>
* use gridOptions.appScopeProvider to override the default assignment of $scope.$parent with any reference
*/
self.appScope = self.options.appScopeProvider;

self.headerHeight = self.options.headerRowHeight;

Expand Down
11 changes: 10 additions & 1 deletion src/js/core/factories/GridOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,20 @@ angular.module('ui.grid')
* custom row template. Can be set to either the name of a template file:
* <pre> $scope.gridOptions.rowTemplate = 'row_template.html';</pre>
* inline html
* <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>
* <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>
* or the id of a precompiled template (TBD how to use this) can be provided.
* </br>Refer to the custom row template tutorial for more information.
*/
baseOptions.rowTemplate = baseOptions.rowTemplate || 'ui-grid/ui-grid-row';

/**
* @ngdoc object
* @name appScopeProvider
* @propertyOf ui.grid.class:GridOptions
* @description by default, the parent scope of the ui-grid element will be assigned to grid.appScope
* this property allows you to assign any reference you want to grid.appScope
*/
baseOptions.appScopeProvider = baseOptions.appScopeProvider || null;

return baseOptions;
}
Expand Down
6 changes: 3 additions & 3 deletions test/unit/core/directives/ui-grid-footer-cell.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('uiGridFooterCell', function () {
$scope.extScope = 'test';

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

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

var header = $(grid).find('.ui-grid-header-cell:nth(0)');
expect(header).toBeDefined();
expect(header.scope().getExternalScopes).toBeDefined();
expect(header.scope().getExternalScopes()).toBe('test');
expect(header.scope().grid.appScope).toBeDefined();
expect(header.scope().grid.appScope.extScope).toBe('test');
});
});
});
6 changes: 3 additions & 3 deletions test/unit/core/directives/ui-grid-header-cell.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('uiGridHeaderCell', function () {
$scope.extScope = 'test';

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

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

var header = $(grid).find('.ui-grid-header-cell:nth(0)');
expect(header).toBeDefined();
expect(header.scope().getExternalScopes).toBeDefined();
expect(header.scope().getExternalScopes()).toBe('test');
expect(header.scope().grid.appScope).toBeDefined();
expect(header.scope().grid.appScope.extScope).toBe('test');
});
});

Expand Down
Loading

0 comments on commit 7f336d4

Please sign in to comment.