mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
99 lines
3.5 KiB
JavaScript
99 lines
3.5 KiB
JavaScript
function delegateService(methodNames) {
|
|
|
|
if (methodNames.indexOf('$getByHandle') > -1) {
|
|
throw new Error("Method '$getByHandle' is implicitly added to each delegate service. Do not list it as a method.");
|
|
}
|
|
|
|
function trueFn() { return true; }
|
|
|
|
return ['$log', function($log) {
|
|
|
|
/*
|
|
* Creates a new object that will have all the methodNames given,
|
|
* and call them on the given the controller instance matching given
|
|
* handle.
|
|
* The reason we don't just let $getByHandle return the controller instance
|
|
* itself is that the controller instance might not exist yet.
|
|
*
|
|
* We want people to be able to do
|
|
* `var instance = $ionicScrollDelegate.$getByHandle('foo')` on controller
|
|
* instantiation, but on controller instantiation a child directive
|
|
* may not have been compiled yet!
|
|
*
|
|
* So this is our way of solving this problem: we create an object
|
|
* that will only try to fetch the controller with given handle
|
|
* once the methods are actually called.
|
|
*/
|
|
function DelegateInstance(instances, handle) {
|
|
this._instances = instances;
|
|
this.handle = handle;
|
|
}
|
|
methodNames.forEach(function(methodName) {
|
|
DelegateInstance.prototype[methodName] = instanceMethodCaller(methodName);
|
|
});
|
|
|
|
|
|
/**
|
|
* The delegate service (eg $ionicNavBarDelegate) is just an instance
|
|
* with a non-defined handle, a couple extra methods for registering
|
|
* and narrowing down to a specific handle.
|
|
*/
|
|
function DelegateService() {
|
|
this._instances = [];
|
|
}
|
|
DelegateService.prototype = DelegateInstance.prototype;
|
|
DelegateService.prototype._registerInstance = function(instance, handle, filterFn) {
|
|
var instances = this._instances;
|
|
instance.$$delegateHandle = handle;
|
|
instance.$$filterFn = filterFn || trueFn;
|
|
instances.push(instance);
|
|
|
|
return function deregister() {
|
|
var index = instances.indexOf(instance);
|
|
if (index !== -1) {
|
|
instances.splice(index, 1);
|
|
}
|
|
};
|
|
};
|
|
DelegateService.prototype.$getByHandle = function(handle) {
|
|
return new DelegateInstance(this._instances, handle);
|
|
};
|
|
|
|
return new DelegateService();
|
|
|
|
function instanceMethodCaller(methodName) {
|
|
return function caller() {
|
|
var handle = this.handle;
|
|
var args = arguments;
|
|
var foundInstancesCount = 0;
|
|
var returnValue;
|
|
|
|
this._instances.forEach(function(instance) {
|
|
if ((!handle || handle == instance.$$delegateHandle) && instance.$$filterFn(instance)) {
|
|
foundInstancesCount++;
|
|
var ret = instance[methodName].apply(instance, args);
|
|
//Only return the value from the first call
|
|
if (foundInstancesCount === 1) {
|
|
returnValue = ret;
|
|
}
|
|
}
|
|
});
|
|
|
|
if (!foundInstancesCount && handle) {
|
|
return $log.warn(
|
|
'Delegate for handle "' + handle + '" could not find a ' +
|
|
'corresponding element with delegate-handle="' + handle + '"! ' +
|
|
methodName + '() was not called!\n' +
|
|
'Possible cause: If you are calling ' + methodName + '() immediately, and ' +
|
|
'your element with delegate-handle="' + handle + '" is a child of your ' +
|
|
'controller, then your element may not be compiled yet. Put a $timeout ' +
|
|
'around your call to ' + methodName + '() and try again.'
|
|
);
|
|
}
|
|
return returnValue;
|
|
};
|
|
}
|
|
|
|
}];
|
|
}
|