Skip to content

Commit ea25c65

Browse files
authored
Merge pull request #2324 from adumesny/master
Angular module
2 parents 9d740ab + 925ac92 commit ea25c65

16 files changed

+241
-227
lines changed

Gruntfile.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ module.exports = function(grunt) {
4343
'dist/es5/gridstack-poly.js': ['src/gridstack-poly.js'],
4444
'dist/src/gridstack.scss': ['src/gridstack.scss'],
4545
'dist/src/gridstack-extra.scss': ['src/gridstack-extra.scss'],
46-
'dist/ng/README.md': ['demo/angular/src/app/README.md'],
47-
// 'dist/ng/gridstack.component.ts': ['demo/angular/src/app/gridstack.component.ts'],
48-
// 'dist/ng/gridstack-item.component.ts': ['demo/angular/src/app/gridstack-item.component.ts'],
46+
'dist/ng/README.md': ['demo/angular/README.md'],
47+
'dist/ng/src/gridstack.component.ts': ['demo/angular/src/gridstack.component.ts'],
48+
'dist/ng/src/gridstack-item.component.ts': ['demo/angular/src/gridstack-item.component.ts'],
49+
'dist/ng/src/gridstack.module.ts': ['demo/angular/src/gridstack.module.ts'],
4950
}
5051
}
5152
},

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ GridStack no longer requires external dependencies as of v1.0.0 (lodash was remo
147147

148148
search for ['gridstack' under NPM](https://www.npmjs.com/search?q=gridstack&ranking=popularity) for latest, more to come...
149149

150-
- **Angular**: we now ship out of the box with Angular wrapper components - see <a href="https://github.com/gridstack/gridstack.js/tree/master/demo/angular/src/app" target="_blank">Angular Demo</a>.
150+
- **Angular**: we now ship out of the box with Angular wrapper components - see <a href="https://github.com/gridstack/gridstack.js/tree/master/demo/angular" target="_blank">Angular Demo</a>.
151151
- **Angular9**: [lb-gridstack](https://github.com/pfms84/lb-gridstack) Note: very old v0.3 gridstack instance so recommend for **concept ONLY if you wish to use directive instead**. teh code has been vented as I use components.
152152
- **AngularJS**: [gridstack-angular](https://github.com/kdietrich/gridstack-angular)
153153
- **Ember**: [ember-gridstack](https://github.com/yahoo/ember-gridstack)

demo/angular/README.md

Lines changed: 168 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,168 @@
1-
2-
see [**Angular wrapper doc**](./src/app/README.md) for actual usage. this is generic ng project info...
3-
4-
# Angular
5-
6-
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.13.
7-
8-
## Development server
9-
10-
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
11-
12-
## Code scaffolding
13-
14-
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
15-
16-
## Build
17-
18-
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
19-
20-
## Running unit tests
21-
22-
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
23-
24-
## Running end-to-end tests
25-
26-
Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
27-
28-
## Further help
29-
30-
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
31-
1+
# Angular wrapper
2+
3+
The Angular [wrapper component](./gridstack.component.ts) <gridstack> is a better way to use Gridstack, but alternative raw [ngFor](./ngFor.ts) or [simple](./simple.ts) demos are also given.
4+
5+
# Dynamic grid items
6+
this is the recommended way if you are going to have multiple grids (alow drag&drop between) or drag from toolbar to create items, or drag to remove items, etc...
7+
8+
I.E. don't use Angular templating to create grid items as that is harder to sync when gridstack will also add/remove items.
9+
10+
HTML
11+
```html
12+
<gridstack [options]="gridOptions">
13+
</gridstack>
14+
```
15+
16+
CSS
17+
```css
18+
@import "gridstack/dist/gridstack.min.css";
19+
20+
.grid-stack {
21+
background: #FAFAD2;
22+
}
23+
.grid-stack-item-content {
24+
text-align: center;
25+
background-color: #18bc9c;
26+
}
27+
```
28+
29+
Code
30+
```ts
31+
import { GridStack, GridStackOptions } from 'gridstack';
32+
import { gsCreateNgComponents } from 'gridstack/dist/ng/gridstack.component';
33+
34+
constructor() {
35+
// use the built in component creation code
36+
GridStack.addRemoveCB = gsCreateNgComponents;
37+
}
38+
39+
// sample grid options and items to load...
40+
public gridOptions: GridStackOptions = {
41+
margin: 5,
42+
float: true,
43+
children: [ // or call load()/addWidget() with same data
44+
{x:0, y:0, minW:2, content:'Item 1'},
45+
{x:1, y:1, content:'Item 2'},
46+
{x:2, y:2, content:'Item 3'},
47+
]
48+
}
49+
```
50+
51+
# More Complete example
52+
In this example will use your actual custom angular components inside each grid item (instead of dummy html content)
53+
54+
HTML
55+
```html
56+
<gridstack [options]="gridOptions" (changeCB)="onChange($event)">
57+
<div empty-content>message when grid is empty</div>
58+
</gridstack>
59+
```
60+
61+
Code
62+
```ts
63+
import { Component } from '@angular/core';
64+
import { GridStack, GridStackOptions } from 'gridstack';
65+
import { GridstackComponent, gsCreateNgComponents, NgGridStackWidget, nodesCB } from 'gridstack/dist/ng/gridstack.component';
66+
67+
// some custom components
68+
@Component({
69+
selector: 'app-a',
70+
template: 'Comp A', // your real ng content goes in each component instead...
71+
})
72+
export class AComponent {
73+
}
74+
75+
@Component({
76+
selector: 'app-b',
77+
template: 'Comp B',
78+
})
79+
export class BComponent {
80+
}
81+
82+
// .... in your module for example
83+
constructor() {
84+
// register all our dynamic components created in the grid
85+
GridstackComponent.addComponentToSelectorType([AComponent, BComponent]);
86+
// set globally our method to create the right widget type
87+
GridStack.addRemoveCB = gsCreateNgComponents;
88+
GridStack.saveCB = gsSaveAdditionalNgInfo;
89+
}
90+
91+
// and now our content will look like instead of dummy html content
92+
public gridOptions: NgGridStackOptions = {
93+
margin: 5,
94+
float: true,
95+
minRow: 1, // make space for empty message
96+
children: [ // or call load()/addWidget() with same data
97+
{x:0, y:0, minW:2, type:'app-a'},
98+
{x:1, y:1, type:'app-b'},
99+
{x:2, y:2, content:'plain html content'},
100+
]
101+
}
102+
103+
// called whenever items change size/position/etc.. see other events
104+
public onChange(data: nodesCB) {
105+
console.log('change ', data.nodes.length > 1 ? data.nodes : data.nodes[0]);
106+
}
107+
```
108+
109+
# ngFor with wrapper
110+
For simple case where you control the children creation (gridstack doesn't do create or re-parenting)
111+
112+
HTML
113+
```html
114+
<gridstack [options]="gridOptions" (changeCB)="onChange($event)">
115+
<gridstack-item *ngFor="let n of items; trackBy: identify" [options]="n">
116+
Item {{n.id}}
117+
</gridstack-item>
118+
</gridstack>
119+
```
120+
121+
Code
122+
```javascript
123+
import { GridStackOptions, GridStackWidget } from 'gridstack';
124+
import { nodesCB } from 'gridstack/dist/ng/gridstack.component';
125+
126+
/** sample grid options and items to load... */
127+
public gridOptions: GridStackOptions = {
128+
margin: 5,
129+
float: true,
130+
}
131+
public items: GridStackWidget[] = [
132+
{x:0, y:0, minW:2, id:'1'}, // must have unique id used for trackBy
133+
{x:1, y:1, id:'2'},
134+
{x:2, y:2, id:'3'},
135+
];
136+
137+
// called whenever items change size/position/etc..
138+
public onChange(data: nodesCB) {
139+
console.log('change ', data.nodes.length > 1 ? data.nodes : data.nodes[0]);
140+
}
141+
142+
// ngFor unique node id to have correct match between our items used and GS
143+
public identify(index: number, w: GridStackWidget) {
144+
return w.id; // or use index if no id is set and you only modify at the end...
145+
}
146+
```
147+
148+
## Demo
149+
You can see a fuller example at [app.component.ts](https://github.com/gridstack/gridstack.js/blob/master/demo/angular/src/app/app.component.ts)
150+
151+
to build the demo, go to demo/angular and run `yarn` + `yarn start` and Navigate to `http://localhost:4200/`
152+
153+
Code now shipped starting with v8.0+ in dist/ng for people to use directly!
154+
## Caveats
155+
156+
- This wrapper needs:
157+
- gridstack v8 to run as it needs the latest changes (use older version that matches GS versions)
158+
- Angular 13+ for dynamic createComponent() API
159+
160+
## *ngFor Caveats
161+
- This wrapper handles well ngFor loops, but if you're using a trackBy function (as I would recommend) and no element id change after an update,
162+
you must manually update the `GridstackItemComponent.option` directly - see [modifyNgFor()](./app.component.ts#L174) example.
163+
- The original client list of items is not updated to match **content** changes made by gridstack (TBD later), but adding new item or removing (as shown in demo) will update those new items. Client could use change/added/removed events to sync that list if they wish to do so.
164+
165+
166+
Would appreciate getting help doing the same for React and Vue (2 other popular frameworks)
167+
168+
-Alain

demo/angular/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@angular/platform-browser": "^15.1.1",
1919
"@angular/platform-browser-dynamic": "^15.1.1",
2020
"@angular/router": "^15.1.1",
21-
"gridstack": "^8.1.0",
21+
"gridstack": "^8.1.1",
2222
"rxjs": "~7.8.1",
2323
"tslib": "^2.3.0",
2424
"zone.js": "~0.13.0"

demo/angular/src/app/README.md

Lines changed: 0 additions & 154 deletions
This file was deleted.

demo/angular/src/app/app.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
22
import { GridStack, GridStackOptions, GridStackWidget } from 'gridstack';
3-
import { GridstackComponent, NgGridStackOptions, NgGridStackWidget, elementCB, gsCreateNgComponents, nodesCB } from './gridstack.component';
3+
import { GridstackComponent, NgGridStackOptions, NgGridStackWidget, elementCB, gsCreateNgComponents, nodesCB } from '../gridstack.component';
44
import { AngularSimpleComponent } from './simple';
55
import { AngularNgForTestComponent } from './ngFor';
66
import { AngularNgForCmdTestComponent } from './ngFor_cmd';

0 commit comments

Comments
 (0)