diff --git a/js/ext/angular/src/controller/ionicScrollController.js b/js/ext/angular/src/controller/ionicScrollController.js
index 0011d15133..23a858603c 100644
--- a/js/ext/angular/src/controller/ionicScrollController.js
+++ b/js/ext/angular/src/controller/ionicScrollController.js
@@ -13,6 +13,9 @@ angular.module('ionic.ui.scroll')
var element = this.element = scrollViewOptions.el;
var scrollView = this.scrollView = new ionic.views.Scroll(scrollViewOptions);
+ this.$scope = $scope;
+ $scope.$parent.$$ionicScrollController = this;
+
if (!angular.isDefined(scrollViewOptions.bouncing)) {
ionic.Platform.ready(function() {
scrollView.options.bouncing = !ionic.Platform.isAndroid();
diff --git a/js/ext/angular/src/directive/ionicBar.js b/js/ext/angular/src/directive/ionicBar.js
index 25bfb2ac9f..f954e09f08 100644
--- a/js/ext/angular/src/directive/ionicBar.js
+++ b/js/ext/angular/src/directive/ionicBar.js
@@ -7,8 +7,7 @@ angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize'])
return {
restrict: 'C',
link: function($scope, $element, $attr) {
- // We want to scroll to top when the top of this element is clicked
- $ionicScrollDelegate.tapScrollToTop($element);
+ $ionicScrollDelegate($scope).tapScrollToTop($element);
}
};
}])
@@ -26,8 +25,9 @@ angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize'])
* Is able to have left or right buttons, and additionally its title can be
* aligned through the {@link ionic.controller:ionicBar ionicBar controller}.
*
- * @param {string=} model The model to assign this headerBar's
- * {@link ionic.controller:ionicBar ionicBar controller} to.
+ * @param {string=} type The type of the bar. For example 'bar-positive'.
+ * @param {string=} model The model to assign this headerBar's
+ * {@link ionic.controller:ionicBar ionicBar controller} to.
* Defaults to assigning to $scope.headerBarController.
* @param {string=} align-title Where to align the title at the start.
* Avaialble: 'left', 'right', or 'center'. Defaults to 'center'.
@@ -63,8 +63,9 @@ angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize'])
* Is able to have left or right buttons, and additionally its title can be
* aligned through the {@link ionic.controller:ionicBar ionicBar controller}.
*
- * @param {string=} model The model to assign this footerBar's
- * {@link ionic.controller:ionicBar ionicBar controller} to.
+ * @param {string=} type The type of the bar. For example 'bar-positive'.
+ * @param {string=} model The model to assign this footerBar's
+ * {@link ionic.controller:ionicBar ionicBar controller} to.
* Defaults to assigning to $scope.footerBarController.
* @param {string=} align-title Where to align the title at the start.
* Avaialble: 'left', 'right', or 'center'. Defaults to 'center'.
@@ -90,9 +91,9 @@ angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize'])
function barDirective(isHeader) {
var BAR_TEMPLATE = isHeader ?
'' :
- '';
- var BAR_MODEL_DEFAULT = isHeader ?
- 'headerBarController' :
+ '';
+ var BAR_MODEL_DEFAULT = isHeader ?
+ 'headerBarController' :
'footerBarController';
return ['$parse', function($parse) {
return {
@@ -106,7 +107,12 @@ function barDirective(isHeader) {
alignTitle: $attr.alignTitle || 'center'
});
- $parse($attr.model || BAR_MODEL_DEFAULT).assign($scope.$parent, hb);
+ $parse($attr.model || BAR_MODEL_DEFAULT).assign($scope.$parent || $scope, hb);
+
+ $attr.$observe('type', function(val, oldVal) {
+ oldVal && $element.removeClass(oldVal);
+ $element.addClass(val);
+ });
}
};
}];
diff --git a/js/ext/angular/src/directive/ionicContent.js b/js/ext/angular/src/directive/ionicContent.js
index 6b5e7c06b4..30f12bf22d 100644
--- a/js/ext/angular/src/directive/ionicContent.js
+++ b/js/ext/angular/src/directive/ionicContent.js
@@ -72,7 +72,7 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) {
require: '^?ionNavView',
scope: true,
template:
- '
' +
+ '
',
compile: function(element, attr, transclude) {
diff --git a/js/ext/angular/src/service/delegates/ionicScrollDelegate.js b/js/ext/angular/src/service/delegates/ionicScrollDelegate.js
index ba98b64cca..1f58595bf3 100644
--- a/js/ext/angular/src/service/delegates/ionicScrollDelegate.js
+++ b/js/ext/angular/src/service/delegates/ionicScrollDelegate.js
@@ -13,7 +13,9 @@ angular.module('ionic.ui.service.scrollDelegate', [])
* {@link ionic.directive:ionContent} or {@link ionic.directive:ionScroll}
* directive).
*
- * Inject it into a controller, and its methods will send messages to the nearest scrollView and all of its children.
+ * Inject it into a controller, create a new instance based upon the current scope,
+ * and its methods will send messages to the nearest scrollView and all of
+ * its children.
*
* @usage
* ```html
@@ -26,167 +28,185 @@ angular.module('ionic.ui.service.scrollDelegate', [])
* ```js
* function MyController($scope, $ionicScrollDelegate) {
* $scope.scrollToTop = function() {
- * $ionicScrollDelegate.scrollTop();
+ * var delegate = $ionicScrollDelegate($scope);
+ * delegate.scrollTop();
* };
* }
* ```
*/
-.factory('$ionicScrollDelegate', ['$rootScope', '$timeout', '$q', '$anchorScroll', '$location', '$document', function($rootScope, $timeout, $q, $anchorScroll, $location, $document) {
- return {
- /**
- * @ngdoc method
- * @name $ionicScrollDelegate#scrollTop
- * @param {boolean=} shouldAnimate Whether the scroll should animate.
- */
- scrollTop: function(animate) {
- $rootScope.$broadcast('scroll.scrollTop', animate);
- },
- /**
- * @ngdoc method
- * @name $ionicScrollDelegate#scrollBottom
- * @param {boolean=} shouldAnimate Whether the scroll should animate.
- */
- scrollBottom: function(animate) {
- $rootScope.$broadcast('scroll.scrollBottom', animate);
- },
- /**
- * @ngdoc method
- * @name $ionicScrollDelegate#scroll
- * @param {number} left The x-value to scroll to.
- * @param {number} top The y-value to scroll to.
- * @param {boolean=} shouldAnimate Whether the scroll should animate.
- */
- scrollTo: function(left, top, animate) {
- $rootScope.$broadcast('scroll.scrollTo', left, top, animate);
- },
- /**
- * @ngdoc method
- * @name $ionicScrollDelegate#anchorScroll
- * @description Tell the scrollView to scroll to the element with an id
- * matching window.location.hash.
- *
- * If no matching element is found, it will scroll to top.
- *
- * @param {boolean=} shouldAnimate Whether the scroll should animate.
- */
- anchorScroll: function(animate) {
- $rootScope.$broadcast('scroll.anchorScroll', animate);
- },
- /**
- * @ngdoc method
- * @name $ionicScrollDelegate#resize
- * @description Tell the scrollView to recalculate the size of its container.
- */
- resize: function() {
- $rootScope.$broadcast('scroll.resize');
- },
- /**
- * @private
- */
- tapScrollToTop: function(element, animate) {
- var _this = this;
- if (!angular.isDefined(animate)) {
- animate = true;
- }
+.factory('$ionicScrollDelegate', ['$rootScope', '$timeout', '$location', function($rootScope, $timeout, $location) {
- ionic.on('tap', function(e) {
- var target = e.target;
- //Don't scroll to top for a button click
- if (ionic.DomUtil.getParentOrSelfWithClass(target, 'button')) {
- return;
+ function getScrollCtrl($scope) {
+ var ctrl;
+ while ($scope) {
+ if ( (ctrl = $scope.$$ionicScrollController) ) {
+ return ctrl;
+ }
+ $scope = $scope.$parent;
+ }
+ return ctrl;
+ }
+
+ function ionicScrollDelegate($scope) {
+ var scrollCtrl = getScrollCtrl($scope);
+ var scrollScope = scrollCtrl && scrollCtrl.$scope || $rootScope;
+
+ return {
+ /**
+ * @ngdoc method
+ * @name $ionicScrollDelegate#scrollTop
+ * @description Used on an instance of $ionicScrollDelegate.
+ * @param {boolean=} shouldAnimate Whether the scroll should animate.
+ */
+ scrollTop: function(animate) {
+ scrollScope.$broadcast('scroll.scrollTop', animate);
+ },
+ /**
+ * @ngdoc method
+ * @name $ionicScrollDelegate#scrollBottom
+ * @description Used on an instance of $ionicScrollDelegate.
+ * @param {boolean=} shouldAnimate Whether the scroll should animate.
+ */
+ scrollBottom: function(animate) {
+ scrollScope.$broadcast('scroll.scrollBottom', animate);
+ },
+ /**
+ * @ngdoc method
+ * @name $ionicScrollDelegate#scroll
+ * @description Used on an instance of $ionicScrollDelegate.
+ * @param {number} left The x-value to scroll to.
+ * @param {number} top The y-value to scroll to.
+ * @param {boolean=} shouldAnimate Whether the scroll should animate.
+ */
+ scrollTo: function(left, top, animate) {
+ scrollScope.$broadcast('scroll.scrollTo', left, top, animate);
+ },
+ /**
+ * @ngdoc method
+ * @name $ionicScrollDelegate#anchorScroll
+ * @description Used on an instance of $ionicScrollDelegate.
+ *
+ * Tell the scrollView to scroll to the element with an id
+ * matching window.location.hash.
+ *
+ * If no matching element is found, it will scroll to top.
+ *
+ * @param {boolean=} shouldAnimate Whether the scroll should animate.
+ */
+ anchorScroll: function(animate) {
+ scrollScope.$broadcast('scroll.anchorScroll', animate);
+ },
+ /**
+ * @ngdoc method
+ * @name $ionicScrollDelegate#resize
+ * @description Used on an instance of $ionicScrollDelegate.
+ *
+ * Tell the scrollView to recalculate the size of its container.
+ */
+ resize: function() {
+ scrollScope.$broadcast('scroll.resize');
+ },
+ /**
+ * @private
+ */
+ tapScrollToTop: function(element, animate) {
+ var _this = this;
+ if (!angular.isDefined(animate)) {
+ animate = true;
}
- var el = element[0];
- var bounds = el.getBoundingClientRect();
+ ionic.on('tap', function(e) {
+ var target = e.target;
+ //Don't scroll to top for a button click
+ if (ionic.DomUtil.getParentOrSelfWithClass(target, 'button')) {
+ return;
+ }
- if(ionic.DomUtil.rectContains(e.gesture.touches[0].pageX, e.gesture.touches[0].pageY, bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + 20)) {
- _this.scrollTop(animate);
- }
- }, element[0]);
- },
+ var el = element[0];
+ var bounds = el.getBoundingClientRect();
- finishRefreshing: function($scope) {
- $scope.$broadcast('scroll.refreshComplete');
- },
+ if(ionic.DomUtil.rectContains(e.gesture.touches[0].pageX, e.gesture.touches[0].pageY, bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + 20)) {
+ _this.scrollTop(animate);
+ }
+ }, element[0]);
+ },
- /**
- * @private
- * Attempt to get the current scroll view in scope (if any)
- *
- * Note: will not work in an isolated scope context.
- */
- getScrollView: function($scope) {
- return $scope.scrollView;
- },
-
- /**
- * @private
- * Register a scope and scroll view for scroll event handling.
- * $scope {Scope} the scope to register and listen for events
- */
- register: function($scope, $element, scrollView) {
-
- var scrollEl = $element[0];
-
- function scrollViewResize() {
- // Run the resize after this digest
- return $timeout(function() {
- scrollView.resize();
- });
+ /**
+ * @private
+ * Attempt to get the current scroll view in scope (if any)
+ *
+ * Note: will not work in an isolated scope context.
+ */
+ getScrollView: function() {
+ return scrollCtrl && scrollCtrl.scrollView;
}
+ };
+ }
- $element.on('scroll', function(e) {
- var detail = (e.originalEvent || e).detail || {};
+ /**
+ * @private
+ * Register a scope and scroll view for scroll event handling.
+ * $scope {Scope} the scope to register and listen for events
+ */
+ ionicScrollDelegate.register = function($scope, $element, scrollView) {
- $scope.$onScroll && $scope.$onScroll({
- event: e,
- scrollTop: detail.scrollTop || 0,
- scrollLeft: detail.scrollLeft || 0
- });
+ var scrollEl = $element[0];
- });
-
- $scope.$parent.$on('scroll.resize', scrollViewResize);
-
- // Called to stop refreshing on the scroll view
- $scope.$parent.$on('scroll.refreshComplete', function(e) {
- scrollView.finishPullToRefresh();
- });
-
- $scope.$parent.$on('scroll.anchorScroll', function(e, animate) {
- scrollViewResize().then(function() {
- var hash = $location.hash();
- var elm;
- if (hash && (elm = document.getElementById(hash)) ) {
- var scroll = ionic.DomUtil.getPositionInParent(elm, scrollEl);
- scrollView.scrollTo(scroll.left, scroll.top, !!animate);
- } else {
- scrollView.scrollTo(0,0, !!animate);
- }
- });
- });
-
- $scope.$parent.$on('scroll.scrollTo', function(e, left, top, animate) {
- scrollViewResize().then(function() {
- scrollView.scrollTo(left, top, !!animate);
- });
- });
- $scope.$parent.$on('scroll.scrollTop', function(e, animate) {
- scrollViewResize().then(function() {
- scrollView.scrollTo(0, 0, !!animate);
- });
- });
- $scope.$parent.$on('scroll.scrollBottom', function(e, animate) {
- scrollViewResize().then(function() {
- var sv = scrollView;
- if (sv) {
- var max = sv.getScrollMax();
- sv.scrollTo(max.left, max.top, !!animate);
- }
- });
+ function scrollViewResize() {
+ // Run the resize after this digest
+ return $timeout(function() {
+ scrollView.resize();
});
}
+
+ $element.on('scroll', function(e) {
+ var detail = (e.originalEvent || e).detail || {};
+
+ $scope.$onScroll && $scope.$onScroll({
+ event: e,
+ scrollTop: detail.scrollTop || 0,
+ scrollLeft: detail.scrollLeft || 0
+ });
+
+ });
+
+ $scope.$on('scroll.resize', scrollViewResize);
+
+ $scope.$on('scroll.anchorScroll', function(e, animate) {
+ scrollViewResize().then(function() {
+ var hash = $location.hash();
+ var elm;
+ if (hash && (elm = document.getElementById(hash)) ) {
+ var scroll = ionic.DomUtil.getPositionInParent(elm, scrollEl);
+ scrollView.scrollTo(scroll.left, scroll.top, !!animate);
+ } else {
+ scrollView.scrollTo(0,0, !!animate);
+ }
+ });
+ });
+
+ $scope.$on('scroll.scrollTo', function(e, left, top, animate) {
+ scrollViewResize().then(function() {
+ scrollView.scrollTo(left, top, !!animate);
+ });
+ });
+ $scope.$on('scroll.scrollTop', function(e, animate) {
+ scrollViewResize().then(function() {
+ scrollView.scrollTo(0, 0, !!animate);
+ });
+ });
+ $scope.$on('scroll.scrollBottom', function(e, animate) {
+ scrollViewResize().then(function() {
+ var sv = scrollView;
+ if (sv) {
+ var max = sv.getScrollMax();
+ sv.scrollTo(max.left, max.top, !!animate);
+ }
+ });
+ });
};
+
+ return ionicScrollDelegate;
}]);
})(ionic);
diff --git a/js/ext/angular/test/anchorScroll.html b/js/ext/angular/test/anchorScroll.html
index eb1cd83442..743f5719a1 100644
--- a/js/ext/angular/test/anchorScroll.html
+++ b/js/ext/angular/test/anchorScroll.html
@@ -23,7 +23,7 @@