ionic-team / ionic-v1

The repo for Ionic 1.x. For the latest version of Ionic, please see https://github.com/ionic-team/ionic
Other
193 stars 187 forks source link

bug: scrollTop doesn't work inside a modal #25

Open jgw96 opened 7 years ago

jgw96 commented 7 years ago

From @mshima on December 15, 2015 17:37

Type: bug

Platform: all

I need a modal to be shown in different parts of the application so I implemented it inside a service. When the criteria changes or the modal hides the modal should be scrolled to the top.

When calling $ionicScrollDelegate.$getByHandle('??').scrollTop() the DelegateService filters the delegates based on $$delegateHandle name and the function $$filterFn;

The function passed by $ionicScroll is return $ionicHistory.isActiveScope() Seems that $ionHistory ignores modals completely. Is this a bug?? The scrollTop will work only if the modal is created inside a controller and the controller scope is passed to the modal.

Copied from original issue: driftyco/ionic#4795

jgw96 commented 7 years ago

From @mshima on December 15, 2015 17:37

Don't know if it is too intrusive but DelegateService can be changed like this:

Index: ionic.bundle.js
===================================================================
--- ionic.bundle.js
+++ ionic.bundle.js
@@ -98,9 +98,16 @@
           var args = arguments;
           var foundInstancesCount = 0;
           var returnValue;
+          var foundDefferedInstancesCount = 0;
+          var deffered;

           this._instances.forEach(function(instance) {
-            if ((!handle || handle == instance.$$delegateHandle) && instance.$$filterFn(instance)) {
+            if ((!handle || handle == instance.$$delegateHandle)) {
+              if(instance.$$filterFn(instance)){
+                foundDefferedInstancesCount++;
+                deffered = instance;
+                return;
+              }
               foundInstancesCount++;
               var ret = instance[methodName].apply(instance, args);
               //Only return the value from the first call
@@ -110,6 +117,20 @@
             }
           });

+          // $$filterFn will only succeed if the scope (passed on the modal creation)
+          // is active on $ionHistory.
+          // If no scope is passed the the $rootScope is used.
+          //
+          // The modal's scope will never be active on ionHistory.
+          // Seems that $ionHistory ignores modals completely. Is this a bug??
+          //
+          // So if you know the $$delegateHandle name and there is only delegate with this name
+          // execute it. Probably is a modal (or a hidden singleton view??) 
+          if(!foundInstancesCount && foundDefferedInstancesCount && foundDefferedInstancesCount == 1){
+            foundInstancesCount ++;
+            returnValue = deffered[methodName].apply(instance, args);;
+          }
+
           if (!foundInstancesCount && handle) {
             return $log.warn(
               'Delegate for handle "' + handle + '" could not find a ' +
jgw96 commented 7 years ago

From @mshima on December 15, 2015 17:48

This change on $ionicScroll will work as an workaround but seems other delegates should benefit from the DelegateService change.

Index: ionic.bundle.js
===================================================================
--- ionic.bundle.js (revision 20832)
+++ ionic.bundle.js (revision 20833)
@@ -57338,6 +57329,7 @@
 .controller('$ionicScroll', [
   '$scope',
   'scrollViewOptions',
+  '$log',
   '$timeout',
   '$window',
   '$location',
@@ -57346,6 +57338,7 @@
   '$ionicHistory',
 function($scope,
          scrollViewOptions,
+         $log,
          $timeout,
          $window,
          $location,
@@ -57379,8 +57372,15 @@
     .data('$$ionicScrollController', self);

   var deregisterInstance = $ionicScrollDelegate._registerInstance(
-    self, scrollViewOptions.delegateHandle, function() {
-      return $ionicHistory.isActiveScope($scope);
+    self, scrollViewOptions.delegateHandle, function(instance) {
+      var ret = $ionicHistory.isActiveScope($scope);
+      if(!ret && instance.$$delegateHandle && instance.$$delegateHandle.indexOf("-modal") > -1){
+        $log.warn(
+                'Delegate for handle "' + instance.$$delegateHandle + '" is not active.'
+               );
+        return true;
+      }
+      return ret;
     }
   );
jgw96 commented 7 years ago

From @Alexintosh on February 2, 2016 12:59

I'm having all kind of scroll problems inside modals with ionic 1.2.4.

None of these methods works for me:

$ionicScrollDelegate.scrollTo(0, 9999999999);
$ionicScrollDelegate.scrollBottom(true);
$ionicScrollDelegate.$getByHandle('mainScroll').scrollBottom();

Also I'm not able to scroll inside a textarea if it's inside a modal, works well everywhere else.

jgw96 commented 7 years ago

From @Alexintosh on February 2, 2016 13:28

Update: Using the same $scope in modal will make this works (but the modal it's not smooth at all), before I was creating a totally new scope: var scope = $rootScope.$new();

For future reference: To fix any element that won't scroll, just add the class "scroll"

jgw96 commented 7 years ago

Hello! @mshima are you still experiencing this issue or were you able to add the scroll class and fix it?

jgw96 commented 7 years ago

From @mshima on March 14, 2016 20:6

Hello @jgw96, the fix Alexintosh used is to reuse the same $scope just like I told in the last paragraph (poorly explained sorry).

Adding the scroll class will not fix this bug.

In my case I implemented a modal as a singleton that will be opened in more than one controller. Reuse the controller’s scope is not an option. I am using the first patch I provided.

Em 14 de mar de 2016, à(s) 16:48, Justin Willis notifications@github.com escreveu:

Hello! @mshima https://github.com/mshima are you still experiencing this issue or were you able to add the scroll class and fix it?

— Reply to this email directly or view it on GitHub https://github.com/driftyco/ionic/issues/4795#issuecomment-196493919.

jgw96 commented 7 years ago

Thank for the info @mshima ! Will have to look at this some more.

jgw96 commented 7 years ago

From @panlina on November 16, 2016 17:44

passing $scope.$new() does the trick also.

corysmc commented 7 years ago

I'm seeing the same thing. Note $scope.$new() can't be used in my case because my modal is inside a service as well.

daweedm commented 7 years ago

Any release planned fixing this issue ?

finibuhai commented 7 years ago

I'm in the same case as @corysmc. My modal is inside a service. Is there a workaround?