[ ] Angular |
AngularJS . , , , , JS , .
2017 / . , Angular 2/4 ( Angular) enterprise .
.
: , enterprise-level .
, , . , , .
( 1.5),
. , , - .
Angular -.
Breaking Changes,
Angular 4 production-ready.
, Angular TypeScript.
, ,
Angular.
TypeScript, .. ,
. enterprise TypeScript . ES7/8 IE9.
TypeScript IDE. , TS .
, 95% .
5% Vue.js ( ) , , AngularJS, React.
React, AngularJS (HTML + Mustache).
AngularJS, , ,
, React AngularJS, .
, production, AngularJS 1.5-1.6.
Angular , ( , ).
TypeScript.
:
import {Component} from "shared-front/app/decorators";
import FileService, {ContentType, IFile} from "../file.service";
import AlertService from "shared/alert.service";
@Component({
template: require("./file.component.html"),
bindings: {
item: "<",
},
})
export default class FileComponent {
public static $inject = ["fileService"];
public item: IFile;
constructor(private fileService: FileService, private alertService: AlertService) {
}
public isVideo() {
return this.item.contentKeyType === ContentType.VIDEO;
}
public downloadFile() {
this.fileService.download(this.getFileDownloadUrl()).then(() => {
this.alertService.success();
});
}
private getFileDownloadUrl() {
return `url-for-download${this.item.text}`;
}
}
, , TS.
Unit-, 2.
AngularJS , React, , .
, AngularJS. , .
, Angular 2 ( 4) .
, , . , alpha-RC 0. .
, , .
Angular:
import {Component} from '@angular/core';
import FileService, {ContentType, IFile} from "../file.service";
import AlertService from "shared/alert.service";
@Component({
selector: 'app-file',
templateUrl: './file.component.html',
styleUrls: ['./file.component.scss']
})
export class FileComponent {
Input() item: IFile;
constructor(private fileService: FileService, private alertService: AlertService) {
}
public isVideo() {
return this.item.contentKeyType === ContentType.VIDEO;
}
public downloadFile() {
this.fileService.download(this.getFileDownloadUrl()).subscribe(() => {
this.alertService.success();
});
}
private getFileDownloadUrl() {
return `url-for-download${this.item.text}`;
}
}
, .
, Angular 4 Angular CLI
CLI , // .
, Angular. .
, AngularJS, -. (), , . .
CLI " ", React (create-react-app) Vue (vue-cli). , , .
, , ,
.
, .
RxJS, .. .
An Ajax request is singular, and running methods like Observable.prototype.map when there will only ever be one value in the pipe makes no semantic sense. Promises on the other hand represent a value that has yet to be fulfilled, which is exactly what a HTTP request gives you. I spent hours forcing Observables to behave before giving up using Observable.prototype.toPromise to transform the Observable back to a Promise and simply using Promise.all, which works much better than anything Rx.js offers.
, RxJS, ,
Observable, .
After much discussion with the parties involved, I plan to withdraw the Object.observe proposal from TC39 (where it currently sits at stage 2 in the ES spec process), and hope to remove support from V8 by the end of the year (the feature is used on 0.0169% of Chrome pageviews, according to chromestatus.com).
, Rx . , , .
TypeScript', , .
, Angular
( , ), .
, TypeScript' Angular.
.
TypeScript Angular API.
TypeScript , . , API, Angular , .
:
- Angular HttpParams
.
, , Angular , .
:
let params = new HttpParams();
params.set('param', param);
params.set('anotherParam', anotherParam);
...
this.http.get('test', {params: params});
. ?
, TypeScript Angular .
TypeScript
This class is immuatable all mutation operations return a new instance.
, .
http
.post('/api/items/add', body, {
params: new HttpParams().set('id', '3'),
})
.subscribe();
, Angular Observable
, .
RxJS. , Rx , Observable
:
// rx.js
Rx.Observable.create();
vs
// Angular
new Observable()
, Rx + TypeScript + Angular.
RxJS , do
:
observable.do(event => {...})
, .
, :
ERROR TypeError: observable.do is not a function
( ) :
import 'rxjs/add/operator/do';
, TypeScript? . .
, API .
.
, , , , .
instanceof
( , ):
this.router.events.subscribe(event => {
if(event instanceof NavigationStart) {
...
}
}
. - :
this.router.navigate(['/some']);
...
this.router.navigate(['/other']);
?
any[]
.
TypeScript .
, Angular.
AngularJS ,
enum.
, 'some'.
, Angular TypeScript .
, ,
TypeScript , #
{
path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule',
},
, -.
API reactive forms:
// ?
// name c ??
this.heroForm = this.fb.group({
name: ['', Validators.required ],
});
// ??
this.heroForm = this.fb.group({
name: '', // <--- the FormControl called "name"
});
this.complexForm = fb.group({
// compose ?
// null ??
'lastName': [null, Validators.compose([Validators.required, Validators.minLength(5), Validators.maxLength(10)])],
'gender' : [null, Validators.required],
})
[disabled] ...
, , API
TypeScript' Angular .
, , __metadata
.
__metadata
///, ,
.
, .
, AngularJS , @Component
:
export const Component = (options: ng.IComponentOptions = {}) => controller => angular.extend(options, {controller});
TypeScript AngularJS .
Angular, , ,
reflect-metadata . .
, TypeScript,
. TS .
Dependency Injection Angular.
, unit .
, Java- .
, AngularJS , Vue , DI.
Angular , , DI , :
constructor(heroService: HeroService) {
this.heroes = heroService.getHeroes();
}
TypeScript , , @Inject
:
constructor(@Inject(APP_CONFIG) config: AppConfig) {
this.title = config.title;
}
, @Injectable()
.
, , , .
Consider adding @Injectable() to every service class, even those that don't have dependencies and, therefore, do not technically require it.
Here's why:
Future proofing: No need to remember @Injectable() when you add a dependency later.
Consistency: All services follow the same rules, and you don't have to wonder why a decorator is missing.
Always write@Injectable()
, not just@Injectable
. The application will fail mysteriously if you forget the parentheses.
, , TypeScript Angular .
, .
Angular. .
, :
style using ngStyle
Hello Wordl!
CSS class using property syntax, this text is blue
object of classes
array of classes
string of classes
, .
Binding | Example |
---|---|
Properties | |
Events | |
Two-way |
Visualize a banana in a box to remember that the parentheses go inside the brackets.
Angular , ,
, .
Vue.
, , 6 ,
.. .
Angular View encapsulation.
Shadow DOM .
Shadow DOM.
CSS :
.first {
background-color: red;
}
.first .second {
background-color: green;
}
.first .second .third {
background-color: blue;
}
Angular :
.first[_ngcontent-c1] {
background-color: red;
}
.first[_ngcontent-c1] .second[_ngcontent-c1] {
background-color: green;
}
.first[_ngcontent-c1] .second[_ngcontent-c1] .third[_ngcontent-c1] {
background-color: blue;
}
.
Vue , :
.first[data-v-50646cd8] {
background-color: red;
}
.first .second[data-v-50646cd8] {
background-color: green;
}
.first .second .third[data-v-50646cd8] {
background-color: blue;
}
, Vue scoped .
, Vue (vue-cli webpack) SASS/SCSS, Angular CLI ng set defaults.styleExt scss
.
, webpack.
, , .
UI PrimeNG,
:
body .ui-tree .ui-treenode .ui-treenode-content .ui-tree-toggler {
font-size: 1.1em;
}
, .
:
body :host >>> .ui-tree .ui-treenode .ui-treenode-content .ui-tree-toggler {
font-size: 2em;
}
!important
.
PrimeNG , , Angular.
>>>
/deep/
shadow-piercing .
"" Shadow DOM .
Angular ,
, /deep/
>>>
.
, .
, ::ng-deep
shadow-piercing Angular .
(4.2.6 -> 4.3.0), ( NPM ^
).
, ChangeLog Angular 4, . .
::ng-deep
.
, PrimeNG, .
: Shadow DOM .
, , Angular HTML . .
Angular , , AngularJS HTML () .
AngularJS : .
//.
.
.
,
CUSTOM_ELEMENTS_SCHEMA
-
...
const TAG_DEFINITIONS: {[key: string]: HtmlTagDefinition} = {
'base': new HtmlTagDefinition({isVoid: true}),
'meta': new HtmlTagDefinition({isVoid: true}),
'area': new HtmlTagDefinition({isVoid: true}),
'embed': new HtmlTagDefinition({isVoid: true}),
'link': new HtmlTagDefinition({isVoid: true}),
'img': new HtmlTagDefinition({isVoid: true}),
'input': new HtmlTagDefinition({isVoid: true}),
'param': new HtmlTagDefinition({isVoid: true}),
'hr': new HtmlTagDefinition({isVoid: true}),
'br': new HtmlTagDefinition({isVoid: true}),
'source': new HtmlTagDefinition({isVoid: true}),
'track': new HtmlTagDefinition({isVoid: true}),
'wbr': new HtmlTagDefinition({isVoid: true}),
'p': new HtmlTagDefinition({
closedByChildren: [
'address', 'article', 'aside', 'blockquote', 'div', 'dl', 'fieldset', 'footer', 'form',
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr',
'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'
],
closedByParent: true
}),
...
'td': new HtmlTagDefinition({closedByChildren: ['td', 'th'], closedByParent: true}),
'th': new HtmlTagDefinition({closedByChildren: ['td', 'th'], closedByParent: true}),
'col': new HtmlTagDefinition({requiredParents: ['colgroup'], isVoid: true}),
'svg': new HtmlTagDefinition({implicitNamespacePrefix: 'svg'}),
'math': new HtmlTagDefinition({implicitNamespacePrefix: 'math'}),
'li': new HtmlTagDefinition({closedByChildren: ['li'], closedByParent: true}),
'dt': new HtmlTagDefinition({closedByChildren: ['dt', 'dd']}),
'dd': new HtmlTagDefinition({closedByChildren: ['dt', 'dd'], closedByParent: true}),
'rb': new HtmlTagDefinition({closedByChildren: ['rb', 'rt', 'rtc'
...
,
, webpack , .
JIT .
, AOT .
--aot
, , ng serve
. ( ).
,
.
:
don't use default exports :)
Just place both export types and it works
AOT:
@NgModule({
providers: [
{provide: SomeSymbol, useFactor: (i) => i.get('someSymbol'), deps: ['$injector']}
]
})
export class MyModule {}
:
export factoryForSomeSymbol = (i) => i.get('someSymbol');
@NgModule({
providers: [
{provide: SomeSymbol, useFactor: factoryForSomeSymbol, deps: ['$injector']}
]
})
export class MyModule {}
, .
Angular Zone.js.
, . :
core.es5.js:1020 ERROR Error: Uncaught (in promise): Error: No clusteredNodeId supplied to updateClusteredNode.
Error: No clusteredNodeId supplied to updateClusteredNode.
at ClusterEngine.updateClusteredNode (vis.js:47364)
at VisGraphDataService.webpackJsonp.../../../../../src/app/services/vis-graph-data.service.ts.VisGraphDataService.updateNetwork (vis-graph-data.service.ts:84)
at vis-graph-display.service.ts:63
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
at Object.onInvoke (core.es5.js:3890)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:390)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run (zone.js:141)
at zone.js:818
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
at Object.onInvokeTask (core.es5.js:3881)
at ClusterEngine.updateClusteredNode (vis.js:47364)
at VisGraphDataService.webpackJsonp.../../../../../src/app/services/vis-graph-data.service.ts.VisGraphDataService.updateNetwork (vis-graph-data.service.ts:84)
at vis-graph-display.service.ts:63
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
at Object.onInvoke (core.es5.js:3890)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:390)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run (zone.js:141)
at zone.js:818
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
at Object.onInvokeTask (core.es5.js:3881)
at resolvePromise (zone.js:770)
at zone.js:696
at zone.js:712
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
at Object.onInvoke (core.es5.js:3890)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:390)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run (zone.js:141)
at zone.js:818
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:424)
at Object.onInvokeTask (core.es5.js:3881)
.
, .
- , .
, UI . , -. , UI framework .
, , UI ,
.
UI Angular: https://angular.io/resources ( UI components).
.
, Angular Material 2 , Angular .
, , .
, Angular Material 2 , , , .. , , . multiple-select, .
.
Feature | Status |
---|---|
tree | In-progress |
stepper | In-progress, planned Q3 2017 |
sticky-header | In-progress, planned Q3 2017 |
virtual-repeat | Not started, planned Q4 2017 |
fab speed-dial | Not started, not planned |
fab toolbar | Not started, not planned |
bottom-sheet | Not started, not planned |
bottom-nav | Not started, not planned |
, Bootstrap
ng2-bootstrap () ngx-bootstrap.
, CSS, ( modal, datepicker typeahead).
. ( Tree Table!).
PrimeFaces .. JSF, . PrimeNG ( ). , , .
.
.
, ,
, PrimeNG .
( ) Clarity vmware.
UI , CSS .
bootstrap. / .
,
datepicker' select2- .
:
DatePicker,
Select 2.0
( , , ).
, "Clarity Design System" Angular
( enterprise ).
VMware .
,
.
, Angular UI .
?
Angular VMware. enterprise? .
, .
Vue.js :
Element (~15k stars), Vue Material
( Angular Material 2 ),
Vuetify ( Material ),
Quasar,
iView Muse-UI
(iView , ).
, , , Vue .
,
, .
Clarity , Angular .
, Angular,
.
, .
Vue.js.
webpack vue-cli .
, all-in-one,
Vue , Angular.
, UI framework' .
TypeScript,
.
React? AngularJS Vue,
v-if
, v-model
v-for
.
, , Aurelia ,
Vue .
, - Angular community - ,
enterprise framework', .
, .
, 4 Angular, .
Vue...