Skip to content

Commit

Permalink
docs: refactor pipe example to use the HttpClient
Browse files Browse the repository at this point in the history
docs: fix typos in 'Httpclient' docs (angular#19127)

PR Close angular#19127

docs(router): add `paramsInheritanceStrategy` documentation (angular#22590)

PR Close angular#22590

docs: add app.module to changed documents (angular#23876)

PR Close angular#23876

docs: clarify faqs about services (angular#24079)

PR Close angular#24079

docs(aio): added a link to Angular Zero online course (Traditional Chinese) (angular#24228)

PR Close angular#24228

docs: describe rounding behaviour of 'DecimalPipe' (angular#24303)

PR Close angular#24303

docs(common): fix in the documentation of PUT (angular#24528)
PR Close angular#24528

docs: add workspace and related cli terms (angular#24633)

PR Close angular#24633

docs(changelog): correct inaccuracies (angular#24713)
PR Close angular#24713

test: integration test for TS 2.9.x (angular#24749)

PR Close angular#24749

fix(ivy): pipes are pure by default (angular#24750)

PR Close angular#24750

build(bazel): update to rule_nodejs 0.10.0 (angular#24759)

PR Close angular#24759

build: upgrade jasmine (and related typings) to latest version (angular#19904)

With these changes, the types are a little stricter now and also not
compatible with Protractor's jasmine-like syntax. So, we have to also
use `@types/jasminewd2` for e2e tests (but not for non-e2e tests).

I also had to "augment" `@types/jasminewd2`, because the latest
typings from [DefinitelyTyped][1] do not reflect the fact that the
`jasminewd2` version (v2.1.0) currently used by Protractor supports
passing a `done` callback to a spec.

[1]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/566e0394859fdc1dc893658ccec6b06372d56a91/types/jasminewd2/index.d.ts#L9-L15

Fixes angular#23952
Closes angular#24733

PR Close angular#19904

test: make `NgMatchers` type-aware (angular#19904)

PR Close angular#19904

refactor: infer type for `it()` assertion functions (angular#19904)

PR Close angular#19904

build: upgrade jasmine to 2.99.x and fix tests (angular#19904)

PR Close angular#19904

refactor: re-organize and "modernize" cjs-jasmine scripts (angular#19904)

PR Close angular#19904

test: run unit tests in random order (angular#19904)

PR Close angular#19904

build: upgrade jasmine to 3.1.0 (angular#19904)

PR Close angular#19904

build: upgrade karma and related dependencies (angular#19904)

PR Close angular#19904

docs: refactored ng-container code (angular#22742)


PR Close angular#22742

docs: update Angular Boot Camp description (angular#23653)

PR Close angular#23653

feat(service-worker): add support for `?` in SW config globbing (angular#24105)

The globbing is used in the following sections:
- `assetGroups` > `resources` > `files`/`versionedFiles`
- `assetGroups` > `resources` > `urls`
- `dataGroups` > `urls`
- `navigationUrls`

Query params are ignored for `files`/`versionedFiles` and
`navigationUrls`, but they are still taken into account for
`assetGroups`/`dataGroups` `urls`. To avoid a breaking change, `?` is
matched literally for these patterns.

PR Close angular#24105

refactor(service-worker): avoid unnecessary operations and remove unused code (angular#24127)

PR Close angular#24127

fix(service-worker): avoid network requests when looking up hashed resources in cache (angular#24127)

PR Close angular#24127

feat(ivy): properly apply style="", [style], [style.foo] and [attr.style] bindings (angular#24602)

PR Close angular#24602

fix(language-service): do not overwrite native `Reflect` (angular#24299)

Fixes angular#21420

PR Close angular#24299

fix(common): use correct currency format for locale de-AT (angular#24658)

Fixes angular#24609
PR Close angular#24658

fix(ivy): correctly resolve Array  property access (angular#24664)

PR Close angular#24664

build: make `internal-angular` karma reporter compatible with latest karma (angular#24803)

Due to changes in karma@1.0.0, `internal-angular` karma reporter stopped
showing browser logs (such as `console.log()` etc.).
Related to d571a51.

PR Close angular#24803

build: remove unnecessary `internal-angular` karma reporter (angular#24803)

The reporter was added in 87d56ac, with the purpose of fixing
source-map paths (which was apparently needed back then). Things have
moved around a lot since then and the custom reporter doesn't seem to be
necessary any more. By removing the reporter, we have one less thing to
worry about while upgrading karma; plus we get improvements in built-in
reporters for free.

Output with the custom reporter:
```
at someMethod (packages/core/.../some-file.ts:13:37)
```

Output with the built-in reporter:
```
at someMethod (packages/core/.../some-file.ts:13.37 <- dist/all/@angular/core/.../some-file.js:1:337)
```

PR Close angular#24803

fix(core): mark NgModule as not the root if APP_ROOT is set to false (angular#24814)

Tree shakable providers use the APP_ROOT token to determine where to attach themselves. APP_ROOT gets set on NgModule with BrowserModule irrespective of whether it is actually the root(Ex. in case of SSR app where the shell app is first bootstrapped without BrowserModule being the root module).

This change allows a NgModule with BrowserModule to explicitly mark itself as not the root by setting APP_ROOT token to false. This allows tree shakable providers to be attached to the right rott module.

PR Close angular#24814

fix(platform-browser): mark Meta and Title services as tree shakable providers (angular#24815)

This lets services that use Meta and Title services to be tree shakable and provided in root.

PR Close angular#24815

docs(aio): unified console.log single string style (angular#22737)
PR Close angular#22737

docs: unified console.log single string style (angular#22737)


PR Close angular#22737

fix(compiler-cli): Use typescript to resolve modules for metadata (angular#22856)

The current module resolution simply attaches .ts to the import/export path, which does
not work if the path is using Node / CommonJS behavior to resolve to an index.ts file.
This patch uses typescript's module resolution logic, and will attempt to load the original
typescript file if this resolution returns a .js or .d.ts file

PR Close angular#22856

docs: clarify wording in architecture overview (angular#24481)

Closes angular#23463
Closes angular#22158

PR Close angular#24481

docs: add tree-shakable providers (angular#24481)

PR Close angular#24481

fix(ivy): support projecting into dynamic views (angular#24752)

PR Close angular#24752

refactor(ivy): replace pNextOrParent with TNode props (angular#24752)

PR Close angular#24752

docs: fix typo in Universal guide (angular#24812)

PR Close angular#24812

fix(platform-browser): workaround wrong import path generated by ngc for DOCUMENT (angular#24830)


docs: correct project definition (angular#24807)

PR Close angular#24807

build: update to latest nodejs bazel rules (angular#24817)

PR Close angular#24817

fix(common): do not round factional seconds (angular#24831)

fixes angular#24384

PR Close angular#24831

docs: fix typos referencing inline component styles (angular#22557)

PR Close angular#22557

fix(router): add ability to recover from malformed url (angular#23283)

Fixes angular#21468

PR Close angular#23283

docs: fix incorrect forms selector references (angular#22631)

PR Close angular#22631

docs(aio): unified string chaining (angular#22735)
PR Close angular#22735

docs: unified string chaining (angular#22735)


PR Close angular#22735

docs(forms): added missing backtick (angular#24451)

Fixed trivial markdown problem with a missing backtick.

PR Close angular#24451

docs(forms): update API reference for form validators (angular#24734)

PR Close angular#24734

Merge remote-tracking branch 'upstream/master' into refactor-example-pipe
  • Loading branch information
danielsogl committed Jul 18, 2018
1 parent 23dc9a9 commit 35032da
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 46 deletions.
17 changes: 7 additions & 10 deletions aio/content/examples/pipes/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
// #docregion
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';
import { ExponentialStrengthPipe } from './exponential-strength.pipe';
import { FetchJsonPipe } from './fetch-json.pipe';
import {
FlyingHeroesComponent,
FlyingHeroesImpureComponent
} from './flying-heroes.component';
import { FlyingHeroesImpurePipe, FlyingHeroesPipe } from './flying-heroes.pipe';
import { HeroAsyncMessageComponent } from './hero-async-message.component';
import { HeroBirthdayComponent } from './hero-birthday1.component';
import { HeroBirthday2Component } from './hero-birthday2.component';
import { HeroListComponent } from './hero-list.component';
import { PowerBoosterComponent } from './power-booster.component';
import { PowerBoostCalculatorComponent } from './power-boost-calculator.component';
import {
FlyingHeroesPipe,
FlyingHeroesImpurePipe
} from './flying-heroes.pipe';
import { FetchJsonPipe } from './fetch-json.pipe';
import { ExponentialStrengthPipe } from './exponential-strength.pipe';
import { PowerBoosterComponent } from './power-booster.component';

@NgModule({
imports: [
Expand All @@ -43,6 +40,6 @@ import { ExponentialStrengthPipe } from './exponential-strength.pipe';
FetchJsonPipe,
ExponentialStrengthPipe
],
bootstrap: [ AppComponent ]
bootstrap: [AppComponent]
})
export class AppModule { }
export class AppModule {}
9 changes: 5 additions & 4 deletions aio/content/examples/pipes/src/app/fetch-json.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
// #docregion
import { HttpClient } from '@angular/common/http';
import { Pipe, PipeTransform } from '@angular/core';
import { HttpClient } from '@angular/common/http';

// #docregion pipe-metadata
@Pipe({
name: 'fetch',
pure: false
})
// #enddocregion pipe-metadata
export class FetchJsonPipe implements PipeTransform {
export class FetchJsonPipe implements PipeTransform {
private cachedData: any = null;
private cachedUrl = '';

constructor(private http: HttpClient) { }
constructor(private http: HttpClient) {}

transform(url: string): any {
if (url !== this.cachedUrl) {
this.cachedData = null;
this.cachedUrl = url;
this.http.get(url).subscribe( result => this.cachedData = result );
this.http.get(url).subscribe(result => (this.cachedData = result));
}

return this.cachedData;
Expand Down
2 changes: 1 addition & 1 deletion aio/content/guide/architecture-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Angular inserts an instance of the `HeroListComponent` view between those tags.

* `templateUrl`: The module-relative address of this component's HTML template. Alternatively, you can provide the HTML template inline, as the value of the `template` property. This template defines the component's _host view_.

* `providers`: An array of **dependency injection providers** for services that the component requires. In the example, this tells Angular how to provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display.
* `providers`: An array of **dependency injection providers** for services that the component requires. In the example, this tells Angular how provide the `HeroService` instance that the component's constructor uses to get the list of heroes to display.

<hr/>

Expand Down
8 changes: 4 additions & 4 deletions modules/benchmarks/src/tree/render3/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export class TreeComponent {
s(c0);
{ T(1); }
e();
C(2);
C(3);
C(4);
}
if (rf & RenderFlags.Update) {
sp(0, 0, ctx.data.depth % 2 ? '' : 'grey');
Expand All @@ -67,7 +67,7 @@ export class TreeComponent {
}
}
cr();
cR(3);
cR(4);
{
if (ctx.data.right != null) {
let rf0 = V(0);
Expand Down Expand Up @@ -117,8 +117,8 @@ export function TreeTpl(rf: RenderFlags, ctx: TreeNode) {
s(c1);
{ T(2); }
e();
C(3);
C(4);
C(5);
}
e();
}
Expand All @@ -134,7 +134,7 @@ export function TreeTpl(rf: RenderFlags, ctx: TreeNode) {
}
}
cr();
cR(4);
cR(5);
{
if (ctx.right != null) {
let rf0 = V(0);
Expand Down
16 changes: 16 additions & 0 deletions packages/common/src/i18n/format_date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,22 @@ function formatFractionalSeconds(milliseconds: number, digits: number): string {
return strMs.substr(0, digits);
}

/**
* Trim a fractional part to `digits` number of digits.
* Right pads with "0" to fit the requested number of digits if needed.
*
* @param num The fractional part value
* @param digits The width of the output
*/
function trimRPadFractional(num: number, digits: number): string {
let strNum = String(num);
// Add padding at the end
while (strNum.length < digits) {
strNum = strNum + 0;
}
return strNum.substr(0, digits);
}

/**
* Returns a date formatter that transforms a date into its locale digit representation
*/
Expand Down
84 changes: 67 additions & 17 deletions packages/core/src/render3/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,21 @@ import {assertDefined, assertEqual, assertLessThan, assertNotDefined, assertNotE
import {throwCyclicDependencyError, throwErrorIfNoChangesMode, throwMultipleComponentError} from './errors';
import {executeHooks, executeInitHooks, queueInitHooks, queueLifecycleHooks} from './hooks';
import {ACTIVE_INDEX, LContainer, RENDER_PARENT, VIEWS} from './interfaces/container';
import {ComponentDefInternal, ComponentQuery, ComponentTemplate, DirectiveDefInternal, DirectiveDefListOrFactory, InitialStylingFlags, PipeDefListOrFactory, RenderFlags} from './interfaces/definition';
import {ComponentDefInternal, ComponentQuery, ComponentTemplate, DirectiveDefInternal, DirectiveDefListOrFactory, PipeDefListOrFactory, RenderFlags} from './interfaces/definition';
import {LInjector} from './interfaces/injector';
import {AttributeMarker, InitialInputData, InitialInputs, LContainerNode, LElementNode, LNode, LProjectionNode, LTextNode, LViewNode, PropertyAliasValue, PropertyAliases, TAttributes, TContainerNode, TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node';
import {CssSelectorList, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection';
import {LQueries} from './interfaces/query';
import {ProceduralRenderer3, RComment, RElement, RText, Renderer3, RendererFactory3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, CurrentMatchesList, DIRECTIVES, FLAGS, HEADER_OFFSET, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, RootContext, SANITIZER, TAIL, TData, TVIEW, TView} from './interfaces/view';
import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTEXT, CurrentMatchesList, DIRECTIVES, FLAGS, HEADER_OFFSET, HOST_NODE, INJECTOR, LViewData, LViewFlags, NEXT, PARENT, QUERIES, RENDERER, RootContext, SANITIZER, TAIL, TData, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {appendChild, appendProjectedNode, canInsertNativeNode, createTextNode, findComponentHost, getChildLNode, getLViewChild, getNextLNode, getParentLNode, insertView, removeView} from './node_manipulation';
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
import {StylingContext, StylingIndex, allocStylingContext, createStylingContextTemplate, renderStyling as renderElementStyles, updateClassProp as updateElementClassProp, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling';
import {assertDataInRangeInternal, isDifferent, loadElementInternal, loadInternal, stringify} from './util';
import {StylingContext, allocStylingContext, createStylingContextTemplate, renderStyles as renderElementStyles, updateStyleMap as updateElementStyleMap, updateStyleProp as updateElementStyleProp} from './styling';
import {isDifferent, stringify} from './util';
import {ViewRef} from './view_ref';



/**
* Directive (D) sets a property on all component instances using this constant as a key and the
* component's host node (LElement) as the value. This is used in methods like detectChanges to
Expand Down Expand Up @@ -1340,6 +1339,62 @@ function getStylingContext(index: number): StylingContext {
return stylingContext;
}

/**
* Assign any inline style values to the element during creation mode.
*
* This instruction is meant to be called during creation mode to apply all styling
* (e.g. `style="..."`) values to the element. This is also where the provided index
* value is allocated for the styling details for its corresponding element (the element
* index is the previous index value from this one).
*
* (Note this function calls `elementStylingApply` immediately when called.)
*
*
* @param index Index value which will be allocated to store styling data for the element.
* (Note that this is not the element index, but rather an index value allocated
* specifically for element styling--the index must be the next index after the element
* index.)
* @param styles A key/value map of CSS styles that will be registered on the element.
* Each individual style will be used on the element as long as it is not overridden
* by any styles placed on the element by multiple (`[style]`) or singular (`[style.prop]`)
* bindings. If a style binding changes its value to null then the initial styling
* values that are passed in here will be applied to the element (if matched).
*/
export function elementStyling<T>(index: number, styles?: (string | number)[] | null): void {
const tNode = load<LElementNode>(index - 1).tNode;
if (!tNode.stylingTemplate) {
// initialize the styling template.
tNode.stylingTemplate = createStylingContextTemplate(styles);
}
// Allocate space but leave null for lazy creation.
viewData[index + HEADER_OFFSET] = null;
if (styles && styles.length) {
elementStylingApply(index);
}
}

/**
* Retrieve the `StylingContext` at a given index.
*
* This method lazily creates the `StylingContext`. This is because in most cases
* we have styling without any bindings. Creating `StylingContext` eagerly would mean that
* every style declaration such as `<div style="color: 'red' ">` would result `StyleContext`
* which would create unnecessary memory pressure.
*
* @param index Index of the style allocation. See: `elementStyling`.
*/
function getStylingContext(index: number): StylingContext {
let stylingContext = load<StylingContext>(index);
if (!stylingContext) {
const lElement: LElementNode = load(index - 1);
const tNode = lElement.tNode;
ngDevMode &&
assertDefined(tNode.stylingTemplate, 'getStylingContext() called before elementStyling()');
stylingContext = viewData[index + HEADER_OFFSET] = allocStylingContext(tNode.stylingTemplate !);
}
return stylingContext;
}

/**
* Apply all styling values to the element which have been queued by any styling instructions.
*
Expand All @@ -1355,7 +1410,7 @@ function getStylingContext(index: number): StylingContext {
* index.)
*/
export function elementStylingApply<T>(index: number): void {
renderElementStyles(getStylingContext(index), renderer);
renderElementStyles(load<LElementNode>(index - 1), getStylingContext(index), renderer);
}

/**
Expand Down Expand Up @@ -1412,17 +1467,12 @@ export function elementStyleProp<T>(
* (Note that this is not the element index, but rather an index value allocated
* specifically for element styling--the index must be the next index after the element
* index.)
* @param styles A key/value style map of the styles that will be applied to the given element.
* Any missing styles (that have already been applied to the element beforehand) will be
* removed (unset) from the element's styling.
* @param classes A key/value style map of CSS classes that will be added to the given element.
* Any missing classes (that have already been applied to the element beforehand) will be
* removed (unset) from the element's list of CSS classes.
*/
export function elementStylingMap<T>(
index: number, styles: {[styleName: string]: any} | null,
classes?: {[key: string]: any} | string | null): void {
updateStylingMap(getStylingContext(index), styles, classes);
* @param value A value indicating if a given style should be added or removed.
* The expected shape of `value` is an object where keys are style names and the values
* are their corresponding values to set. If value is null, then the style is removed.
*/
export function elementStyle<T>(index: number, value: {[styleName: string]: any} | null): void {
updateElementStyleMap(getStylingContext(index), value);
}

//////////////////////////
Expand Down
20 changes: 10 additions & 10 deletions packages/core/test/render3/instructions_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {NgForOfContext} from '@angular/common';

import {RenderFlags, directiveInject} from '../../src/render3';
import {defineComponent} from '../../src/render3/definition';
import {bind, container, element, elementAttribute, elementEnd, elementProperty, elementStart, elementStyleProp, elementStyling, elementStylingApply, elementStylingMap, interpolation1, renderTemplate, text, textBinding} from '../../src/render3/instructions';
import {bind, container, element, elementAttribute, elementClass, elementEnd, elementProperty, elementStart, elementStyle, elementStyleProp, elementStyling, elementStylingApply, interpolation1, renderTemplate, text, textBinding} from '../../src/render3/instructions';
import {InitialStylingFlags} from '../../src/render3/interfaces/definition';
import {AttributeMarker, LElementNode, LNode} from '../../src/render3/interfaces/node';
import {RElement, domRendererFactory3} from '../../src/render3/interfaces/renderer';
Expand All @@ -23,13 +23,13 @@ import {ComponentFixture, TemplateFixture} from './render_util';
describe('instructions', () => {
function createAnchor() {
elementStart(0, 'a');
elementStyling();
elementStyling(1);
elementEnd();
}

function createDiv(initialStyles?: (string | number)[]) {
elementStart(0, 'div');
elementStyling(initialStyles && Array.isArray(initialStyles) ? initialStyles : null);
elementStyling(1, initialStyles && Array.isArray(initialStyles) ? initialStyles : null);
elementEnd();
}

Expand Down Expand Up @@ -193,15 +193,15 @@ describe('instructions', () => {
it('should use sanitizer function', () => {
const t = new TemplateFixture(() => { return createDiv(['background-image']); });
t.update(() => {
elementStyleProp(0, 0, 'url("http://server")', sanitizeStyle);
elementStylingApply(0);
elementStyleProp(1, 0, 'url("http://server")', sanitizeStyle);
elementStylingApply(1);
});
// nothing is set because sanitizer suppresses it.
expect(t.html).toEqual('<div></div>');

t.update(() => {
elementStyleProp(0, 0, bypassSanitizationTrustStyle('url("http://server")'), sanitizeStyle);
elementStylingApply(0);
elementStyleProp(1, 0, bypassSanitizationTrustStyle('url("http://server")'), sanitizeStyle);
elementStylingApply(1);
});
expect((t.hostElement.firstChild as HTMLElement).style.getPropertyValue('background-image'))
.toEqual('url("http://server")');
Expand All @@ -211,15 +211,15 @@ describe('instructions', () => {
describe('elementStyleMap', () => {
function createDivWithStyle() {
elementStart(0, 'div');
elementStyling(['height', InitialStylingFlags.VALUES_MODE, 'height', '10px']);
elementStyling(1, ['height', InitialStylingFlags.INITIAL_STYLES, 'height', '10px']);
elementEnd();
}

it('should add style', () => {
const fixture = new TemplateFixture(createDivWithStyle);
fixture.update(() => {
elementStylingMap(0, {'background-color': 'red'});
elementStylingApply(0);
elementStyle(1, {'background-color': 'red'});
elementStylingApply(1);
});
expect(fixture.html).toEqual('<div style="height: 10px; background-color: red;"></div>');
});
Expand Down

0 comments on commit 35032da

Please sign in to comment.