我正在寻找一种角度模式来实现离子库对其委托模式的作用。
取slide box component,例如:
在视图中使用其指令(<ion-slide-box>
)时,您可以自动在控制器中注入与指令对象关联的某种服务($ionicSlideBoxDelegate
),您可以使用它来控制它方法如:
$ionicSlideBoxDelegate.start() // Start sliding again if the slideBox was stopped
$ionicSlideBoxDelegate.stop() // Stop sliding
$ionicSlideBoxDelegate.next() // Go to the next slide.
$ionicSlideBoxDelegate.previous() // Go to the previous slide
//...
$scope
以下是一些代码来说明我的解决方案。在这个例子中,我试图创建一个伪进度条指令,它将像普通进度条一样运行,但它会自动前进,除非我们将它告诉stop
。除非通过致电complete
告知,否则它永远不会达到100%。
angular.module("fakeProgressbar", [])
.directive 'fakeProgressbar', ->
scope:
handler: '='
restrict: 'E'
replace: false
template: '
<progressbar class="progress-striped active" max="handler.config.max" type="{{handler.config.type}}" value="handler.config.value">
{{ handler.config.value }} %
</progressbar>
'
.factory 'FakeProgressbarHandler', ($interval, $timeout, $q) ->
class FakeProgressbar
start: -> # ...
success: -> # ...
complete: -> # ...
stop: -> # ...
angular.module("app", ["ui.bootstrap", "fakeProgressbar"])
.controller "fakeProgressbarExampleController", ($scope, FakeProgressbarHandler) ->
$scope.fakeProgressbarHandler = new FakeProgressbarHandler()
$scope.fakeProgressbarHandler.start() # start animation inmediately
# now you can do `$scope.fakeProgressbarHandler.stop()` or `$scope.fakeProgressbarHandler.complete()`
<fake-progressbar handler="fakeProgressbarHandler"></fake-progressbar>
此工作代码的完整示例可在此处找到:http://plnkr.co/edit/Ehsuu1nKxeu2W7ktTVFC?p=preview
当然,问题是如何摆脱必须将fakeProgressbarHandler
附加到范围以便稍后将其传递回指令。
离子委托模式似乎是自动实现的。
答案 0 :(得分:1)
离子代表没有太多魔力。无论何时使用该指令,控制器都会使用delegateService注册实例。例如在slideBox中:
https://github.com/driftyco/ionic/blob/master/js/angular/directive/slideBox.js#L127
var deregisterInstance = $ionicSlideBoxDelegate._registerInstance(
slider, $attrs.delegateHandle, function() {
return $ionicHistory.isActiveScope($scope);
}
);
委托代码主要在这里找到:
https://github.com/driftyco/ionic/blob/master/js/utils/delegateService.js
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);
}
};
};
以下是注册(未经测试)的简化示例:
var app = angular.module('app', []);
app.controller('firstController', function($scope, DelegateService) {
$scope.start = function(handle) {
DelegateService.getInstance(handle).start();
};
$scope.stop = function(handle) {
DelegateService.getInstance(handle).stop();
};
});
app.controller('secondController', function($scope, DelegateService) {
$scope.startAll = function() {
Object.keys(DelegateService._instances).forEach(function(handle) {
DelegateService._instances[handle].start();
});
};
$scope.stopAll = function(handle) {
Object.keys(DelegateService._instances).forEach(function(handle) {
DelegateService._instances[handle].stop();
});
};
});
app.directive('someDirective', function(SomeDirectiveDelegate, DelegateService) {
return {
scope: {},
controller: function($scope, $element, $attrs) {
$scope.progress = {
amount: 0
};
var delegate = new SomeDirectiveDelegate($scope.progress);
DelegateService._registerInstance(delegate, $attrs.handle);
},
template: '<div>{{ progress.amount }}</div>'
};
});
app.factory('SomeDirectiveDelegate', function($interval) {
function SomeDirectiveDelegate(progress) {
var interv;
function stop() {
if (interv) {
$interval.cancel(interv);
interv = null;
}
}
function start() {
stop();
interv = $interval(function() {
progress.amount += 1;
}, 100);
}
return {
start: start,
stop: stop,
};
}
return SomeDirectiveDelegate;
});
app.service('DelegateService', function() {
this._instances = {};
this._registerInstance = function(instance, handle) {
this._instances[handle] = instance;
};
this.getInstance = function(handle) {
return this._instances[handle];
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app='app'>
<div ng-controller='firstController'>
<some-directive handle="1"></some-directive>
<button ng-click="start(1)">start1</button>
<button ng-click="stop(1)">stop1</button>
<some-directive handle="2"></some-directive>
<button ng-click="start(2)">start2</button>
<button ng-click="stop(2)">stop2</button>
</div>
<hr>
<div ng-controller='secondController'>
<button ng-click="startAll()">start all</button>
<button ng-click="stopAll()">stop all</button>
</div>
</div>