refactor($service): removed almost all references to scope.$service

- still need to remove from factory
This commit is contained in:
Misko Hevery 2011-11-02 21:37:06 -07:00
parent f684f20c99
commit 16597e8b52
9 changed files with 92 additions and 69 deletions

View file

@ -561,7 +561,7 @@ angular.mock.TzDate = function (offset, timestamp) {
self[methodName] = function() {
throw {
name: "MethodNotImplemented",
message: "Method '" + methodName + "' is not implemented in the TzDate mock"
message: "Method '" + methodName + "' is not implemented in the TzDate mock"
};
};
});

View file

@ -236,7 +236,7 @@ angularDirective("ng:controller", function(expression){
angularDirective("ng:bind", function(expression, element){
element.addClass('ng-binding');
var exprFn = parser(expression).statements();
return function(element) {
return ['$exceptionHandler', '$element', function($exceptionHandler, element) {
var lastValue = Number.NaN;
this.$watch(function(scope) {
// TODO(misko): remove error handling https://github.com/angular/angular.js/issues/347
@ -269,7 +269,7 @@ angularDirective("ng:bind", function(expression, element){
}
}
} catch (e) {
scope.$service('$exceptionHandler')(e);
$exceptionHandler(e);
} finally {
if (hadOwnElement) {
scope.$element = oldElement;
@ -278,7 +278,7 @@ angularDirective("ng:bind", function(expression, element){
}
}
});
};
}];
});
var bindTemplateCache = {};

View file

@ -312,7 +312,7 @@ function $RootScopeProvider(){
try {
current.$eval(asyncQueue.shift());
} catch (e) {
current.$service('$exceptionHandler')(e);
$exceptionHandler(e);
}
}
if ((watchers = current.$$watchers)) {

View file

@ -189,7 +189,7 @@ describe('Binder', function() {
assertTrue(html.indexOf('action="foo();"') > 0 );
});
it('RepeaterAdd', inject(function($rootScope, $compile) {
it('RepeaterAdd', inject(function($rootScope, $compile, $browser) {
var element = $compile('<div><input type="text" ng:model="item.x" ng:repeat="item in items"></div>')($rootScope);
$rootScope.items = [{x:'a'}, {x:'b'}];
$rootScope.$apply();
@ -200,7 +200,7 @@ describe('Binder', function() {
first.val('ABC');
browserTrigger(first, 'keydown');
$rootScope.$service('$browser').defer.flush();
$browser.defer.flush();
expect($rootScope.items[0].x).toEqual('ABC');
}));

View file

@ -230,10 +230,9 @@ describe("resource", function() {
expect(person.name).toEqual('misko');
}));
it('should return the same object when verifying the cache', inject(function($rootScope, $compile) {
it('should return the same object when verifying the cache',
inject(function($rootScope, $compile, $browser, $resource) {
$compile('<div></div>')($rootScope);
var $browser = $rootScope.$service('$browser');
var $resource = $rootScope.$service('$resource');
var Person = $resource('/Person/:id', null, {query: {method:'GET', isArray: true, verifyCache: true}});
$browser.xhr.expectGET('/Person/123').respond('[\n{\n"name":\n"misko"\n}\n]');
var person = Person.query({id:123});

View file

@ -512,12 +512,12 @@ describe("directive", function() {
expect(element.text()).toEqual('hey dude!');
}));
it('should infer injection arguments', inject(function($rootScope, $compile) {
it('should infer injection arguments', inject(function($rootScope, $compile, $xhr) {
temp.MyController = function($xhr){
this.$root.someService = $xhr;
};
var element = $compile('<div ng:controller="temp.MyController"></div>')($rootScope);
expect($rootScope.someService).toBe($rootScope.$service('$xhr'));
expect($rootScope.someService).toBe($xhr);
}));
});

View file

@ -10,7 +10,8 @@ describe('$route', function() {
log += '<init>;';
}
$route.when('/Book/:book/Chapter/:chapter', {controller: BookChapter, template: 'Chapter.html'});
$route.when('/Book/:book/Chapter/:chapter',
{controller: BookChapter, template: 'Chapter.html'});
$route.when('/Blank');
$rootScope.$on('$beforeRouteChange', function(event, next, current) {
log += 'before();';
@ -50,7 +51,8 @@ describe('$route', function() {
}));
it('should match a route that contains special chars in the path', inject(function($route, $location, $rootScope) {
it('should match a route that contains special chars in the path',
inject(function($route, $location, $rootScope) {
$route.when('/$test.23/foo(bar)/:baz', {template: 'test.html'});
$location.path('/test');
@ -71,7 +73,8 @@ describe('$route', function() {
}));
it('should change route even when only search param changes', inject(function($route, $location, $rootScope) {
it('should change route even when only search param changes',
inject(function($route, $location, $rootScope) {
var callback = jasmine.createSpy('onRouteChange');
$route.when('/test', {template: 'test.html'});
@ -105,7 +108,8 @@ describe('$route', function() {
}));
it('should handle unknown routes with "otherwise" route definition', inject(function($route, $location, $rootScope) {
it('should handle unknown routes with "otherwise" route definition',
inject(function($route, $location, $rootScope) {
var onChangeSpy = jasmine.createSpy('onChange');
function NotFoundCtrl() {this.notFoundProp = 'not found!';}
@ -229,7 +233,8 @@ describe('$route', function() {
}));
it('should allow custom redirectTo function to be used', inject(function($route, $location, $rootScope) {
it('should allow custom redirectTo function to be used',
inject(function($route, $location, $rootScope) {
$route.when('/bar/:id/:subid/:subsubid', {template: 'bar.html'});
$route.when('/foo/:id', {redirectTo: customRedirectFn});
@ -267,9 +272,8 @@ describe('$route', function() {
describe('reloadOnSearch', function() {
it('should reload a route when reloadOnSearch is enabled and .search() changes',
inject(function($route, $location, $rootScope) {
var $routeParams = $rootScope.$service('$routeParams'),
reloaded = jasmine.createSpy('route reload');
inject(function($route, $location, $rootScope, $routeParams) {
var reloaded = jasmine.createSpy('route reload');
$route.when('/foo', {controller: FooCtrl});
$rootScope.$on('$beforeRouteChange', reloaded);
@ -399,9 +403,9 @@ describe('$route', function() {
describe('reload', function() {
it('should reload even if reloadOnSearch is false', inject(function($route, $location, $rootScope) {
var $routeParams = $rootScope.$service('$routeParams'),
count = 0;
it('should reload even if reloadOnSearch is false',
inject(function($route, $location, $rootScope, $routeParams) {
var count = 0;
$route.when('/bar/:barId', {controller: FooCtrl, reloadOnSearch: false});

View file

@ -5,8 +5,9 @@ describe('widget: input', function() {
var $compile = null;
var doc = null;
beforeEach(inject(function($rootScope, $compile) {
beforeEach(inject(function($rootScope, $compile, $browser) {
scope = $rootScope;
defer = $browser.defer;
set$compile($compile);
element = null;
compile = function(html, parent) {
@ -18,7 +19,6 @@ describe('widget: input', function() {
}
$compile(element)(scope);
scope.$apply();
defer = scope.$service('$browser').defer;
return scope;
};
}));
@ -88,7 +88,7 @@ describe('widget: input', function() {
};
inputElement.val(' a ');
browserTrigger(inputElement);
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.name).toEqual('a');
expect(log).toEqual('change();');
});
@ -128,7 +128,7 @@ describe('widget: input', function() {
element.val('Kai');
browserTrigger(element, 'change');
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.name).toEqual('Kai');
});
@ -140,7 +140,7 @@ describe('widget: input', function() {
expect(scope.name).toEqual("Misko");
expect(scope.count).toEqual(0);
browserTrigger(element, 'keydown');
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.name).toEqual("Misko");
expect(scope.count).toEqual(0);
});
@ -166,7 +166,7 @@ describe('widget: input', function() {
element.val('1, 2, 3');
browserTrigger(element);
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.list).toEqual(['1', '2', '3']);
});
@ -191,7 +191,7 @@ describe('widget: input', function() {
} catch (e){}
scope.$element.val('123X');
browserTrigger(scope.$element, 'change');
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.$element.val()).toEqual('123X');
expect(scope.age).toEqual(123);
expect(scope.$element).toBeInvalid();
@ -206,25 +206,25 @@ describe('widget: input', function() {
scope.$element.val('a ');
browserTrigger(scope.$element, 'change');
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.$element.val()).toEqual('a ');
expect(scope.list).toEqual(['a']);
scope.$element.val('a ,');
browserTrigger(scope.$element, 'change');
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.$element.val()).toEqual('a ,');
expect(scope.list).toEqual(['a']);
scope.$element.val('a , ');
browserTrigger(scope.$element, 'change');
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.$element.val()).toEqual('a , ');
expect(scope.list).toEqual(['a']);
scope.$element.val('a , b');
browserTrigger(scope.$element, 'change');
scope.$service('$browser').defer.flush();
defer.flush();
expect(scope.$element.val()).toEqual('a , b');
expect(scope.list).toEqual(['a', 'b']);
});
@ -293,9 +293,9 @@ describe('widget: input', function() {
});
it("should process required", function() {
it("should process required", inject(function($formFactory) {
compile('<input type="text" ng:model="price" name="p" required/>', jqLite(document.body));
expect(scope.$service('$formFactory').rootForm.p.$required).toBe(true);
expect($formFactory.rootForm.p.$required).toBe(true);
expect(element.hasClass('ng-invalid')).toBeTruthy();
scope.price = 'xxx';
@ -304,9 +304,9 @@ describe('widget: input', function() {
element.val('');
browserTrigger(element);
scope.$service('$browser').defer.flush();
defer.flush();
expect(element.hasClass('ng-invalid')).toBeTruthy();
});
}));
it('should allow bindings on ng:required', function() {
@ -328,7 +328,7 @@ describe('widget: input', function() {
element.val('abc');
browserTrigger(element);
scope.$service('$browser').defer.flush();
defer.flush();
expect(element).toBeValid();
});
@ -458,18 +458,18 @@ describe('widget: input', function() {
describe('scope declaration', function() {
it('should read the declaration from scope', inject(function($rootScope, $compile) {
var input, $formFactory;
it('should read the declaration from scope', inject(function($rootScope, $compile, $formFactory) {
var input, formFactory;
var element = angular.element('<input type="@MyType" ng:model="abc">');
$rootScope.MyType = function($f, i) {
input = i;
$formFactory = $f;
formFactory = $f;
};
$rootScope.MyType.$inject = ['$formFactory', '$element'];
$compile(element)($rootScope);
expect($formFactory).toBe($rootScope.$service('$formFactory'));
expect(formFactory).toBe($formFactory);
expect(input[0]).toBe(element[0]);
}));
@ -523,7 +523,7 @@ describe('widget: input', function() {
if (value != undefined) {
scope.$element.val(value);
browserTrigger(element, 'keydown');
scope.$service('$browser').defer.flush();
defer.flush();
}
scope.$digest();
}
@ -587,7 +587,7 @@ describe('widget: input', function() {
el.val('xx');
browserTrigger(el, 'keydown');
expect(function() { $rootScope.$service('$browser').defer.flush(); }).
expect(function() { defer.flush(); }).
toThrow('Expected fooRegexp to be a RegExp but was undefined');
dealoc(el);

View file

@ -1,6 +1,10 @@
'use strict';
describe("widget", function() {
beforeEach(inject(function($provide){
$provide.factory('$xhrCache', ['$xhr.cache', identity]);
}));
describe('ng:switch', inject(function($rootScope, $compile) {
it('should switch on value change', inject(function($rootScope, $compile) {
var element = $compile(
@ -56,25 +60,26 @@ describe("widget", function() {
describe('ng:include', inject(function($rootScope, $compile) {
it('should include on external file', inject(function($rootScope, $compile) {
it('should include on external file', inject(function($rootScope, $compile, $xhrCache) {
var element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
var element = $compile(element)($rootScope);
$rootScope.childScope = $rootScope.$new();
$rootScope.childScope.name = 'misko';
$rootScope.url = 'myUrl';
$rootScope.$service('$xhr.cache').data.myUrl = {value:'{{name}}'};
$xhrCache.data.myUrl = {value:'{{name}}'};
$rootScope.$digest();
expect(element.text()).toEqual('misko');
}));
it('should remove previously included text if a falsy value is bound to src', inject(function($rootScope, $compile) {
it('should remove previously included text if a falsy value is bound to src',
inject(function($rootScope, $compile, $xhrCache) {
var element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
var element = $compile(element)($rootScope);
$rootScope.childScope = $rootScope.$new();
$rootScope.childScope.name = 'igor';
$rootScope.url = 'myUrl';
$rootScope.$service('$xhr.cache').data.myUrl = {value:'{{name}}'};
$xhrCache.data.myUrl = {value:'{{name}}'};
$rootScope.$digest();
expect(element.text()).toEqual('igor');
@ -86,11 +91,11 @@ describe("widget", function() {
}));
it('should allow this for scope', inject(function($rootScope, $compile) {
it('should allow this for scope', inject(function($rootScope, $compile, $xhrCache) {
var element = jqLite('<ng:include src="url" scope="this"></ng:include>');
var element = $compile(element)($rootScope);
$rootScope.url = 'myUrl';
$rootScope.$service('$xhr.cache').data.myUrl = {value:'{{"abc"}}'};
$xhrCache.data.myUrl = {value:'{{"abc"}}'};
$rootScope.$digest();
// TODO(misko): because we are using scope==this, the eval gets registered
// during the flush phase and hence does not get called.
@ -102,28 +107,29 @@ describe("widget", function() {
}));
it('should evaluate onload expression when a partial is loaded', inject(function($rootScope, $compile) {
it('should evaluate onload expression when a partial is loaded',
inject(function($rootScope, $compile, $xhrCache) {
var element = jqLite('<ng:include src="url" onload="loaded = true"></ng:include>');
var element = $compile(element)($rootScope);
expect($rootScope.loaded).not.toBeDefined();
$rootScope.url = 'myUrl';
$rootScope.$service('$xhr.cache').data.myUrl = {value:'my partial'};
$xhrCache.data.myUrl = {value:'my partial'};
$rootScope.$digest();
expect(element.text()).toEqual('my partial');
expect($rootScope.loaded).toBe(true);
}));
it('should destroy old scope', inject(function($rootScope, $compile) {
it('should destroy old scope', inject(function($rootScope, $compile, $xhrCache) {
var element = jqLite('<ng:include src="url"></ng:include>');
var element = $compile(element)($rootScope);
expect($rootScope.$$childHead).toBeFalsy();
$rootScope.url = 'myUrl';
$rootScope.$service('$xhr.cache').data.myUrl = {value:'my partial'};
$xhrCache.data.myUrl = {value:'my partial'};
$rootScope.$digest();
expect($rootScope.$$childHead).toBeTruthy();
@ -135,7 +141,8 @@ describe("widget", function() {
describe('a', inject(function($rootScope, $compile) {
it('should prevent default action to be executed when href is empty', inject(function($rootScope, $compile) {
it('should prevent default action to be executed when href is empty',
inject(function($rootScope, $compile) {
var orgLocation = document.location.href,
preventDefaultCalled = false,
event;
@ -152,7 +159,8 @@ describe("widget", function() {
} else {
event = document.createEvent('MouseEvent');
event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
event.initMouseEvent(
'click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
event.preventDefaultOrg = event.preventDefault;
event.preventDefault = function() {
@ -231,7 +239,8 @@ describe("widget", function() {
$log.error.logs.shift();
}));
it('should expose iterator offset as $index when iterating over arrays', inject(function($rootScope, $compile) {
it('should expose iterator offset as $index when iterating over arrays',
inject(function($rootScope, $compile) {
var element = $compile(
'<ul>' +
'<li ng:repeat="item in items" ng:bind="item + $index + \'|\'"></li>' +
@ -241,7 +250,8 @@ describe("widget", function() {
expect(element.text()).toEqual('misko0|shyam1|frodo2|');
}));
it('should expose iterator offset as $index when iterating over objects', inject(function($rootScope, $compile) {
it('should expose iterator offset as $index when iterating over objects',
inject(function($rootScope, $compile) {
var element = $compile(
'<ul>' +
'<li ng:repeat="(key, val) in items" ng:bind="key + \':\' + val + $index + \'|\'"></li>' +
@ -251,7 +261,8 @@ describe("widget", function() {
expect(element.text()).toEqual('frodo:f0|misko:m1|shyam:s2|');
}));
it('should expose iterator position as $position when iterating over arrays', inject(function($rootScope, $compile) {
it('should expose iterator position as $position when iterating over arrays',
inject(function($rootScope, $compile) {
var element = $compile(
'<ul>' +
'<li ng:repeat="item in items" ng:bind="item + \':\' + $position + \'|\'"></li>' +
@ -270,7 +281,8 @@ describe("widget", function() {
expect(element.text()).toEqual('misko:first|shyam:last|');
}));
it('should expose iterator position as $position when iterating over objects', inject(function($rootScope, $compile) {
it('should expose iterator position as $position when iterating over objects',
inject(function($rootScope, $compile) {
var element = $compile(
'<ul>' +
'<li ng:repeat="(key, val) in items" ng:bind="key + \':\' + val + \':\' + $position + \'|\'">' +
@ -309,7 +321,8 @@ describe("widget", function() {
expect(element.text()).toEqual('a|b|Xc|d|X');
}));
it('should ignore non-array element properties when iterating over an array', inject(function($rootScope, $compile) {
it('should ignore non-array element properties when iterating over an array',
inject(function($rootScope, $compile) {
var element = $compile('<ul><li ng:repeat="item in array">{{item}}|</li></ul>')($rootScope);
$rootScope.array = ['a', 'b', 'c'];
$rootScope.array.foo = '23';
@ -319,7 +332,8 @@ describe("widget", function() {
expect(element.text()).toBe('a|b|c|');
}));
it('should iterate over non-existent elements of a sparse array', inject(function($rootScope, $compile) {
it('should iterate over non-existent elements of a sparse array',
inject(function($rootScope, $compile) {
var element = $compile('<ul><li ng:repeat="item in array">{{item}}|</li></ul>')($rootScope);
$rootScope.array = ['a', 'b'];
$rootScope.array[4] = 'c';
@ -382,7 +396,8 @@ describe("widget", function() {
expect(newElements[3]).toEqual(lis[3]);
}));
it('should remove last item when one duplicate instance is removed', inject(function($rootScope, $compile) {
it('should remove last item when one duplicate instance is removed',
inject(function($rootScope, $compile) {
$rootScope.items = [a, a, a];
$rootScope.$digest();
lis = element.find('li');
@ -395,7 +410,8 @@ describe("widget", function() {
expect(newElements[1]).toEqual(lis[1]);
}));
it('should reverse items when the collection is reversed', inject(function($rootScope, $compile) {
it('should reverse items when the collection is reversed',
inject(function($rootScope, $compile) {
$rootScope.items = [a, b, c];
$rootScope.$digest();
lis = element.find('li');
@ -413,7 +429,8 @@ describe("widget", function() {
describe('@ng:non-bindable', function() {
it('should prevent compilation of the owning element and its children', inject(function($rootScope, $compile) {
it('should prevent compilation of the owning element and its children',
inject(function($rootScope, $compile) {
var element = $compile('<div ng:non-bindable><span ng:bind="name"></span></div>')($rootScope);
$rootScope.name = 'misko';
$rootScope.$digest();
@ -429,14 +446,16 @@ describe("widget", function() {
}));
it('should do nothing when no routes are defined', inject(function($rootScope, $compile, $location) {
it('should do nothing when no routes are defined',
inject(function($rootScope, $compile, $location) {
$location.path('/unknown');
$rootScope.$digest();
expect(element.text()).toEqual('');
}));
it('should load content via xhr when route changes', inject(function($rootScope, $compile, $browser, $location, $route) {
it('should load content via xhr when route changes',
inject(function($rootScope, $compile, $browser, $location, $route) {
$route.when('/foo', {template: 'myUrl1'});
$route.when('/bar', {template: 'myUrl2'});
@ -624,7 +643,8 @@ describe("widget", function() {
}));
it('should show single/plural strings with mal-formed inputs', inject(function($rootScope, $compile) {
it('should show single/plural strings with mal-formed inputs',
inject(function($rootScope, $compile) {
$rootScope.email = '';
$rootScope.$digest();
expect(element.text()).toBe('');