Closed MaximShoustin closed 10 years ago
I already posted a solution in the ionic forum, but it isn't in the repo yet, so I'll just copy what I posted back there:
I was having this issue as well, the problem is I am generating the slide boxes dynamically, which means the delegate-handles are supposed to be generated by angular, when I logged the $ionicSlideBoxDelegate, I could see that it had six instances but their delegate-handles weren't being interpolated, they had the angular code as a string: "slider-{{id}}", and I kept getting this error:
Delegate for handle "slider-4" could not find a corresponding element with delegate-handle="slider-4"! enableSlide() was not called! Possible cause: If you are calling enableSlide() immediately, and your element with delegate-handle="slider-4" is a child of your controller, then your element may not be compiled yet. Put a $timeout around your call to enableSlide() and try again.
For this to work, I had to modify the slidebox source code, what I did was to add the delegateHandle attribute in the scope, so this way it is interpolated.
Like this:
scope: { ..., delegateHandle: '@' }
and then I changed this line of code:
var deregisterInstance = $ionicSlideBoxDelegate._registerInstance(slider, $attrs.delegateHandle);
to:
var deregisterInstance = $ionicSlideBoxDelegate._registerInstance(slider, $scope.delegateHandle);
My delegate-handles are now being interpolated and I can also access the handles correctly.
Not sure if this is a "good" solution, hope it helps!
Good catch. I don't know if its good solution, anyways Ionic team must run regression tests and include these changes as bug fix. Thanks,
@ajoslin, want to keep this mind with the slide-box rework?
This is terrible, but for anyone who must use a generated delegate handle, this is a temporary solution where you don't have to hack the source.
In your template:
...
<ion-content delegate-handle="WILLREPLACE" on-scroll="onScroll()">
...
In your corresponding directive:
...
compile: function ($element, attrs) {
attrs.generatedHandle = Math.random().toString(36).substring(7);
$element[0].innerHTML = $element[0].innerHTML.replace('WILLREPLACE', attrs.generatedHandle);
return postLink;
}
...
Hi, When will this fix be available? I upgraded to latest (1.0.0-beta 13) available at ionic website but issue still exits in there.
Nightly fixes this issue but I am seeing some other issues with the nightly.
Thanks
@mhartington Mike, I'm having same issue in 1.0.0-beta.14-nightly-964. Could you please, help to solve this issue?
Thanks!
I had an issue with this and used this workaround which does not involve modifying the ionic source:
Give each slide a unique id which can be an angular binding. Then you just need to filter on the $ionicScrollDelegate instances collection to get the one which has an element with the id you're looking for on.
Here's a quick copy and paste of my code in case it helps:
<ion-slide ng-repeat="page in pages" active-slide="page">
<ion-content id="{{page.name}}">
...
$scope.getScrollPosition = function (page) {
var instances = $ionicScrollDelegate["_instances"];
var instance = _(instances).find(function(ins) {
return ins.$element[0].id === page.name;
});
console.log(JSON.stringify(instance.getScrollPosition()));
};
An universal directive to use random-generated delegate-handle (inspired to @mikesurowiec ) :
angular.module('app').directive('randomDelegateHandle', [function () {
return {
priority: 1000,
restrict: 'A',
compile: function compile(tElement, tAttrs, transclude) {
tAttrs.$set('delegateHandle', Math.random().toString(36).substring(7));
return function postLink(scope, iElement, iAttrs, controller) {}
}
};
}]);
use:
ion-content random-delegate-handle
Still appears to be messy using 1.0.0-rc.1
danfaber's comment above was really useful in working out what the problem is, but the find() fn is not totally portable it seems :(
I just created a very simple service to manage jumping between tabs in my application (which has lots of nested tabs, and breaks quickly using ionic's built in tab delegate functions).
A horrible solution perhaps .... but this is working very reliably for me at the moment, and it bypasses any need to touch the underlying ionic libs. The code below is verbose and non-optimal, but its easy to reason about, and portable.
// A fix for broken ionic tabs delegate
.factory('$tabs', ['$ionicTabsDelegate', function($ionicTabsDelegate) {
return {
get: function(handle) {
var tabs = $ionicTabsDelegate._instances
var theTab = undefined
// Manually walk ionic's internal array of tabs, and find the matching tab
// use angular's built in array iterator for best portability
angular.forEach(tabs, function(v,k){
if (v.$$delegateHandle === handle) {
theTab = v
}
})
return theTab
},
select: function(handle,position) {
console.log('tabs select',handle,position)
var theTab = this.get(handle)
if (theTab !== undefined) {
theTab.select(position)
}
}
}
}])
Usage :
<ion-tabs delegate-handle="MainTabs">
.... lots of tabs in here
</ion-tabs>
.controller('myExamplecontroller', ['$tabs', function($tabs) {
return {
showFirstTab: function() {
$tabs.select('MainTabs',0)
},
showSecondTab: function() {
$tabs.select('MainTabs',1)
},
// etc
}
}])
I think it find a possibility for solve this error "Delegate for handle "my-handle" could not find a corresponding element with delegate-handle..."
This possibility is caused why $ionicSideMenuDelegate.$getByHandle('menuLeftHandle')._instances is a Array
$ionicSideMenuDelegate.$getByHandle('menuLeftHandle')._instances[n]. anyMethod()
Hello is this issue has been solved?
i still have same problem with generated delegate-handle
this is my code
JS Controller
$scope.swapName = "swap00";
$scope.ds = function (sN) { $ionicSlideBoxDelegate.$getByHandle(sN).enableSlide(false); };
HTML
`
`
i get this message: Delegate for handle "swap00" could not find a corresponding element with delegate-handle="swap00"! enableSlide() was not called! Possible cause: If you are calling enableSlide() immediately, and your element with delegate-handle="swap00" is a child of your controller, then your element may not be compiled yet. Put a $timeout around your call to enableSlide() and try again.
I had a similar problem and asked it in StackOverflow and got a great temporary solution to the problem. See it at StackOverflow. So basically set and get the delegate-handle by id of the container.
Hopefully this can help someone in the future.
URL:ionicframework
I think we are use in wrong, look at the API , the attr delegate-handle
accept value type is string
, not expression
, but I think the type of string is not suitable.
hope you can understand what I said. ^-^
Based on @thepi0 's Link I could solve this problem. For someone who needs help, share code here. You can just put this on your controller. To get dynamically created index of the slide box like with ng-repeat
$scope.getSlideBoxDelegateHandle = function(delegateIndex) {
//get all the instances that ionic scroll delegate is handling
var instances = $ionicSlideBoxDelegate["_instances"];
//Create Instance you want to get
var instance = null;
for (var index in instances) {
//set DelegateHandle value with your index
//Ex) instances[index].$$delegateHandle = "slidebox"+index;
//or just instances[index].$$delegateHandle = index;
instances[index].$$delegateHandle = index;
if (index == delegateIndex) {
instance = instances[index];
}
}
return instance; //return the instance
}
usage HTML
`<div class="list" ng-repeat="myIndex in dynamics>
I fixed mine with a custom function with help from @yacaeh 's code above. Basically, instead of comparing indexes, I compared the HTML object of the passed ion-content from the ones available under $ionicScrollDelegate list. Works like charm for me.
function getScrollDelegate(element, $ionicSlideBoxDelegate) {
var instances = $ionicSlideBoxDelegate["_instances"];
//Create Instance you want to get
var instance = null;
for (var index in instances) {
//set DelegateHandle value with your index
//Ex) instances[index].$$delegateHandle = "slidebox"+index;
//or just instances[index].$$delegateHandle = index;
instances[index].$$delegateHandle = instances[index].$$delegateHandle || index;
if (instances[index].$element[0] == element[0]) {
instance = instances[index];
}
}
return instance; //return the instance
}
And in my directive, I called it like below:
var $scroll = $('.scroll-content', el.parent());//selector to get the ion-content element in current view
vm.prevTop = 0;
var handle = getScrollDelegate($scroll, $ionicScrollDelegate);//gets the handle
$scroll.on('scroll', function (e) {
var pos = handle.getScrollPosition();
var cl = pos.top>vm.prevTop ?'go-down' :'go-up';
$(button).removeClass('go-down go-up').addClass(cl);
})
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.
I have 3
ion-slide-box
. Everyone has 3 items.I created two buttons
Next
andback
to simulate sliding by pressing them.However
delegate-handle
doesn't work. I get:Sounds like
delegate-handle
doesn't register properly the instance ids.This is what I have so far:
Template
And this is a DEMO I play with
The issue was posted in Ionic Forum