Permalink
Browse files

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
  • Loading branch information...
1 parent 35375f2 commit 7f336d4907d5f85c82d33538cfed160e3b3f5df8 @swalters swalters committed Jan 21, 2015
View
@@ -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
@@ -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
};
@@ -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>
```
@@ -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 = {
@@ -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
@@ -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">
@@ -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...';
@@ -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">
@@ -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
@@ -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 = [
@@ -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">
@@ -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));
@@ -18,7 +18,6 @@
$scope.grid = uiGridCtrl.grid;
$scope.colContainer = containerCtrl.colContainer;
- $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
containerCtrl.footer = $elm;
@@ -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)
@@ -27,7 +27,6 @@
var renderContainerCtrl = controllers[1];
$scope.grid = uiGridCtrl.grid;
- $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
$scope.renderContainer = uiGridCtrl.grid.renderContainers[renderContainerCtrl.containerId];
@@ -20,7 +20,6 @@
$scope.grid = uiGridCtrl.grid;
$scope.colContainer = containerCtrl.colContainer;
- $scope.getExternalScopes = uiGridCtrl.getExternalScopes;
@@ -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;
}
};
}
@@ -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
@@ -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.
*
@@ -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,
@@ -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;
@@ -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;
}
@@ -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]);
@@ -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');
});
});
});
@@ -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]);
@@ -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');
});
});
Oops, something went wrong.

2 comments on commit 7f336d4

@tisto
tisto commented on 7f336d4 Feb 23, 2015

@swalters First of all thanks for your work on open source software!

Maybe you are not responsible for the releases or I am missing something here. Though, it would be great if breaking changes would be somehow mentioned in the docs. It took me quite a while, to go through all the commits since rc16 to find this change.

Also I don't quite understand the versioning scheme of ui-grid. Version numbers usually have a meaning to developers and integrators (e.g. http://semver.org). If I as an integrator do an upgrade of a minor version (e.g. rc16 -> rc17) I do not expect any breaking changes. I would if I upgrade from a major version or within an alpha release cycle (and I would not complain here in that case). Please consider adopting a semantic versioning scheme to achieve more stable releases and a better experience for integrators.

@btelintelo

Everything tisto experienced, we have had the same issues. Any improvements here would greatly improve new adopters of this project into their code base.

Please sign in to comment.