vendredi 19 juin 2015

how to manage a directive from your controller in angular js

I am looking for a angular pattern to achieves what the ionic library does with its delegate pattern.

Take the slide box component, for example:

When you use its directive (<ion-slide-box>) in your view you can automatically inject in your controller some sort of service ($ionicSlideBoxDelegate) associated to the directive object, that you can use to control it with methods like:

$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
//...

My best attempt:

  1. create a directive with an isolated scope that receives only one parameter (the delegate service object)
  2. in the controller instantiate a new instance of this Delegate service and attach it to the $scope
  3. in the view pass the instance to the Delegate service to the directive

Here is some code to illustrate my solution. In this example I am trying to create a fake progress bar directive that will act like a normal progress bar but it will advance automatically, unless we tell it to stop. And it will never reach 100% unless told to do so by calling to complete.

The directive and its attached Handler (or delegate):

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: -> # ...

In your controller:

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()` 

In your view:

<fake-progressbar handler="fakeProgressbarHandler"></fake-progressbar>

A complete example of this working code can be found here: http://ift.tt/1CgVAWs

The question:

The question is, of course, how to get rid of having to attach the fakeProgressbarHandler to the scope to later pass it back to the directive.

The ionic delegate pattern seems to achieve this automatically.

Aucun commentaire:

Enregistrer un commentaire