Thoughts on using Zurb's Foundation+AngularJS?
Categories:
Integrating Zurb Foundation with AngularJS: A Comprehensive Guide

Explore the considerations, challenges, and best practices for combining Zurb Foundation's responsive frontend framework with AngularJS for dynamic web applications.
Zurb Foundation is a powerful, responsive frontend framework that provides a robust set of UI components and a flexible grid system. AngularJS, on the other hand, is a comprehensive JavaScript framework for building dynamic single-page applications. Combining these two technologies can lead to highly interactive and visually appealing web applications, but it also introduces specific integration challenges and considerations. This article delves into the nuances of using Foundation with AngularJS, offering insights and practical advice for developers.
Understanding the Core Integration Challenge
The primary challenge in integrating Foundation with AngularJS stems from their differing approaches to DOM manipulation and component lifecycle. Foundation often relies on jQuery for its JavaScript plugins, which directly manipulate the DOM. AngularJS, however, prefers to manage the DOM through its data-binding and directive system. Direct jQuery manipulation can interfere with AngularJS's digest cycle and lead to unexpected behavior or performance issues. The key is to ensure that Foundation's JavaScript components are initialized and managed in an 'Angular-friendly' way.
flowchart TD A[Start] --> B{Foundation Component Initialization}; B --> C{Direct jQuery DOM Manipulation?}; C -- Yes --> D[Conflict with AngularJS Digest Cycle]; C -- No --> E[AngularJS Manages DOM]; D --> F[Potential Issues: UI Glitches, Performance]; E --> G[Smooth Integration]; F --> H[Solution: Angular Directives/Wrappers]; G --> H; H --> I[End];
Flowchart illustrating the core integration challenge between Foundation and AngularJS.
Strategies for Effective Integration
To successfully integrate Foundation with AngularJS, developers typically adopt one of several strategies. The most common and recommended approach involves wrapping Foundation components within custom AngularJS directives. This allows AngularJS to control the lifecycle of the Foundation component, ensuring proper initialization, updates, and destruction without direct jQuery interference. Another strategy is to use existing Angular modules that provide wrappers for Foundation components, such as ui-foundation
or similar community projects.
link
function or controller. Use $scope.$on('$destroy', ...)
to clean up any Foundation-specific event listeners or instances.Example: Wrapping a Foundation Reveal Modal in an AngularJS Directive
Let's consider a practical example: integrating Foundation's Reveal modal. Instead of calling $(document).foundation('reveal', 'open')
directly from an AngularJS controller, we can create a directive that encapsulates the modal's behavior. This directive would be responsible for initializing the Reveal plugin and exposing methods to open/close the modal in an Angular-friendly manner.
angular.module('myApp').directive('foundationReveal', function() {
return {
restrict: 'A',
scope: {
isOpen: '=',
options: '='
},
link: function(scope, element, attrs) {
var modal = element.foundation('reveal', scope.options);
scope.$watch('isOpen', function(newVal, oldVal) {
if (newVal && !oldVal) {
modal.foundation('reveal', 'open');
} else if (!newVal && oldVal) {
modal.foundation('reveal', 'close');
}
});
element.on('closed.fndtn.reveal', function() {
scope.$apply(function() {
scope.isOpen = false;
});
});
scope.$on('$destroy', function() {
// Clean up Foundation instance if necessary
element.off('closed.fndtn.reveal');
// Foundation doesn't have a direct 'destroy' method for Reveal,
// but removing the element from DOM usually suffices.
});
}
};
});
AngularJS directive for wrapping a Foundation Reveal modal.
This directive allows you to control the modal's visibility using a simple isOpen
boolean scope property, aligning with AngularJS's declarative approach. The element.on('closed.fndtn.reveal', ...)
ensures that when the modal is closed by Foundation (e.g., by clicking outside), the isOpen
property is updated in the Angular scope.
$(element).hide()
or $(element).show()
within an Angular controller, it's often a sign that you should be using ng-show
, ng-hide
, or a custom directive instead.Considerations for Foundation's JavaScript Components
Not all Foundation components require the same level of directive wrapping. Simple CSS-driven components like the grid system or typography classes integrate seamlessly without any special AngularJS handling. However, components with JavaScript behavior, such as dropdowns, off-canvas menus, accordions, and sliders, will benefit greatly from being managed by Angular directives. Always refer to Foundation's documentation to understand which components rely on JavaScript.
1. Identify JavaScript-Dependent Components
Review the Foundation documentation to determine which UI components rely on JavaScript for their functionality (e.g., Reveal, Dropdown, Off-canvas, Accordion, Equalizer).
2. Create Custom Directives
For each identified JavaScript-dependent component, develop a dedicated AngularJS directive. This directive should handle the component's initialization (.foundation()
), event binding, and cleanup.
3. Bind to Angular Scope
Expose relevant component states or actions (e.g., isOpen
, isActive
, toggle()
) as isolated scope properties or methods within your directive to allow control from parent controllers.
4. Handle Event Propagation
Listen for Foundation's custom events (e.g., closed.fndtn.reveal
, opened.fndtn.dropdown
) within your directive and use $scope.$apply()
to update the Angular scope accordingly.
5. Perform Cleanup on Destroy
Implement $scope.$on('$destroy', ...)
in your directive to unbind event listeners and perform any necessary cleanup to prevent memory leaks.