Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

docs(upgrade): add ngUpgrade guide version 2 #1538

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ declare var angular:any;
// #docregion register
angular.module('heroApp', [])
.service('heroes', HeroesService)
.directive('heroDetail', upgradeAdapter.downgradeNg2Component(HeroDetailComponent));
.directive('heroDetail',
upgradeAdapter.downgradeNg2Component(HeroDetailComponent));

upgradeAdapter.upgradeNg1Provider('heroes');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@
<!-- #docregion usecomponent -->
<div ng-controller="MainController as mainCtrl">
<hero-detail [hero]="mainCtrl.hero"
(deleted)="mainCtrl.onDelete($event)">
(deleted)="mainCtrl.onDelete($event)">
</hero-detail>
</div>
<!-- #enddocregion usecomponent -->
<!-- #docregion userepeatedcomponent -->
<div ng-controller="MainController as mainCtrl">
<hero-detail [hero]="hero"
(deleted)="mainCtrl.onDelete($event)"
ng-repeat="hero in mainCtrl.heroes">
(deleted)="mainCtrl.onDelete($event)"
ng-repeat="hero in mainCtrl.heroes">
</hero-detail>
</div>
<!-- #enddocregion userepeatedcomponent-->
Expand Down
4 changes: 3 additions & 1 deletion public/docs/_examples/upgrade-adapter/ts/index-ng-app.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
</head>

<body ng-app="heroApp" ng-strict-di>
<div id="message" ng-controller="MainCtrl as mainCtrl">{{ mainCtrl.message }}</div>
<div id="message" ng-controller="MainCtrl as mainCtrl">
{{ mainCtrl.message }}
</div>
</body>
</html>
37 changes: 37 additions & 0 deletions public/docs/_examples/upgrade-phonecat-1-typescript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
This is the Angular Phonecat application adjusted to fit our boilerplate project
structure.

The following changes from vanilla Phonecat are applied:

* The TypeScript config file shown in the guide is `tsconfig.ng1.json` instead
of the default, because we don't want to enable `noImplicitAny` for migration.
* Karma config for unit tests is in karma.conf.ng1.js because the boilerplate
Karma config is not compatible with the way Angular 1 tests need to be run.
The shell script run-unit-tests.sh can be used to run the unit tests.
* Instead of using Bower, Angular 1 and its dependencies are fetched from a CDN
in index.html and karma.conf.ng1.js.
* E2E tests have been moved to the parent directory, where `gulp run-e2e-tests` can
discover and run them along with all the other examples.
* Angular 1 typings (from DefinitelyTyped) are added to typings-ng1 so that
TypeScript can recognize Angular 1 code. (typings.json comes from boilerplate
so we can't add them there).
* Most of the phone JSON and image data removed in the interest of keeping
repo weight down. Keeping enough to retain testability of the app.

## Running the app

Start like any example

npm run start

You'll find the app under the /app path: http://localhost:3002/app/index.html

## Running unit tests

./run-unit-tests.sh

## Running E2E tests

Like for any example (at the project root):

gulp run-e2e-tests --filter=phonecat-1
104 changes: 104 additions & 0 deletions public/docs/_examples/upgrade-phonecat-1-typescript/e2e-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
'use strict';

// Angular E2E Testing Guide:
// https://docs.angularjs.org/guide/e2e-testing

describe('PhoneCat Application', function() {

beforeAll(function() {
browser.baseUrl = 'http://localhost:8080/app/';
setProtractorToNg1Mode();
});

it('should redirect `index.html` to `index.html#!/phones', function() {
browser.get('index.html');
expect(browser.getLocationAbsUrl()).toBe('/phones');
});

describe('View: Phone list', function() {

beforeEach(function() {
browser.get('index.html#!/phones');
});

it('should filter the phone list as a user types into the search box', function() {
var phoneList = element.all(by.repeater('phone in $ctrl.phones'));
var query = element(by.model('$ctrl.query'));

expect(phoneList.count()).toBe(20);

query.sendKeys('nexus');
expect(phoneList.count()).toBe(1);

query.clear();
query.sendKeys('motorola');
expect(phoneList.count()).toBe(8);
});

it('should be possible to control phone order via the drop-down menu', function() {
var queryField = element(by.model('$ctrl.query'));
var orderSelect = element(by.model('$ctrl.orderProp'));
var nameOption = orderSelect.element(by.css('option[value="name"]'));
var phoneNameColumn = element.all(by.repeater('phone in $ctrl.phones').column('phone.name'));

function getNames() {
return phoneNameColumn.map(function(elem) {
return elem.getText();
});
}

queryField.sendKeys('tablet'); // Let's narrow the dataset to make the assertions shorter

expect(getNames()).toEqual([
'Motorola XOOM\u2122 with Wi-Fi',
'MOTOROLA XOOM\u2122'
]);

nameOption.click();

expect(getNames()).toEqual([
'MOTOROLA XOOM\u2122',
'Motorola XOOM\u2122 with Wi-Fi'
]);
});

it('should render phone specific links', function() {
var query = element(by.model('$ctrl.query'));
query.sendKeys('nexus');

element.all(by.css('.phones li a')).first().click();
expect(browser.getLocationAbsUrl()).toBe('/phones/nexus-s');
});

});

describe('View: Phone detail', function() {

beforeEach(function() {
browser.get('index.html#!/phones/nexus-s');
});

it('should display the `nexus-s` page', function() {
expect(element(by.binding('$ctrl.phone.name')).getText()).toBe('Nexus S');
});

it('should display the first phone image as the main phone image', function() {
var mainImage = element(by.css('img.phone.selected'));

expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
});

it('should swap the main image when clicking on a thumbnail image', function() {
var mainImage = element(by.css('img.phone.selected'));
var thumbnails = element.all(by.css('.phone-thumbs img'));

thumbnails.get(2).click();
expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/);

thumbnails.get(0).click();
expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
});

});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* Animate `ngRepeat` in `phoneList` component */
.phone-list-item.ng-enter,
.phone-list-item.ng-leave,
.phone-list-item.ng-move {
overflow: hidden;
transition: 0.5s linear all;
}

.phone-list-item.ng-enter,
.phone-list-item.ng-leave.ng-leave-active,
.phone-list-item.ng-move {
height: 0;
margin-bottom: 0;
opacity: 0;
padding-bottom: 0;
padding-top: 0;
}

.phone-list-item.ng-enter.ng-enter-active,
.phone-list-item.ng-leave,
.phone-list-item.ng-move.ng-move-active {
height: 120px;
margin-bottom: 20px;
opacity: 1;
padding-bottom: 4px;
padding-top: 15px;
}

/* Animate view transitions with `ngView` */
.view-container {
position: relative;
}

.view-frame {
margin-top: 20px;
}

.view-frame.ng-enter,
.view-frame.ng-leave {
background: white;
left: 0;
position: absolute;
right: 0;
top: 0;
}

.view-frame.ng-enter {
animation: 1s fade-in;
z-index: 100;
}

.view-frame.ng-leave {
animation: 1s fade-out;
z-index: 99;
}

@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}

@keyframes fade-out {
from { opacity: 1; }
to { opacity: 0; }
}

/* Older browsers might need vendor-prefixes for keyframes and animation! */
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

angular.
module('phonecatApp').
animation('.phone', function phoneAnimationFactory() {
return {
addClass: animateIn,
removeClass: animateOut
};

function animateIn(element: JQuery, className: string, done: () => void) {
if (className !== 'selected') return;

element.css({
display: 'block',
position: 'absolute',
top: 500,
left: 0
}).animate({
top: 0
}, done);

return function animateInEnd(wasCanceled: boolean) {
if (wasCanceled) element.stop();
};
}

function animateOut(element: JQuery, className: string, done: () => void) {
if (className !== 'selected') return;

element.css({
position: 'absolute',
top: 0,
left: 0
}).animate({
top: -500
}, done);

return function animateOutEnd(wasCanceled: boolean) {
if (wasCanceled) element.stop();
};
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// #docregion
angular.
module('phonecatApp').
config(['$locationProvider' ,'$routeProvider',
function config($locationProvider: angular.ILocationProvider,
$routeProvider: angular.route.IRouteProvider) {
$locationProvider.hashPrefix('!');

$routeProvider.
when('/phones', {
template: '<phone-list></phone-list>'
}).
when('/phones/:phoneId', {
template: '<phone-detail></phone-detail>'
}).
otherwise('/phones');
}
]);
Loading