Search code examples
angularjsangularjs-directiveratchet-2

Using Ratchet's Toggle Component with Angular


I'm building a mobile app using Ratchet and Angular, and development has been great and fast.

However, I've run into a lot of trouble when using toggles. Ratchet adds an "active" class in this div when its state is active:

<div class="toggle">
   <div class="toggle-handle"></div>
</div>

However this is done outside of Angular, so my attempts to create a directive to $watch this change has been unsuccessful. Also, I haven't tested it but ngClass probably does not update the model if a class is added outside of Angular.

Ratchet's toggle.js has an event listener that fires when state is changed, but again, not only this is javascript outside of angular, but I am also not using jQuery, so I don't know how to add this callback from a view loaded inside a ng-view, and change the controller scope from such a callback.

Any help is appreciated.


Solution

  • Eventually I solved my problem with a directive, unaware of Ratchet handlers as @kindasimple suggested:

    HTML:

    <div id="variable" class="toggle" my-toggle>
        <div class="toggle-handle"></div>
    </div>
    

    JS:

    app.directive('myToggle', [function() {
    
        function link(scope, element, attrs) {
            scope.$watch(function() {
                return element.hasClass('active');
            }, function(value) {
                var id = element.attr('id');
                scope.save(id, value);
            });
        }
    
        return {
            restrict: 'A',
            scope: false,
            link: link
        };
    }]);
    

    Ratchet toggles an active class on clicks and touches, so my main idea was to $watch() that change. My directives didn't need an isolated scope on their on, I just wanted each toggle to update a variable on its controller's scope, hence the scope: false.

    In my specific code, scope.save() is a controller function to save variables, so I could use it and element id to save its status. But a previous solution used $scope.$apply() inside the controller to force Angular to run a $digest() cycle and call scope.$watch() for the directives.