Implementing simple jQuery plugins with AngularJS (and RequireJS) - javascript

I'm currently using Angular and Require in a project for the first time. At the moment it seems like it's very hard to do the things that should be simple when using Angular.
I'm currently trying to put a click event using jQuery for a simple tabbed menu and of course, $(document).ready will not work because Angular loads the views after this has fired. Are there any examples of how to implement jQuery plugins with Angular (and Require)?
Also, I will need to turn jQuery plugins on/off on window resize using another plugin. What is the correct method of doing these things? Any help would be greatly appreciated.
I've attached some (very) stripped down code from a controller. I have also tried putting the click event straight between the angular.element ready code. Still doesn't seem to work.
define(['app', 'modules/Social'], function(app, social) {
'use strict';
return app.controller('HomeCtrl', function($scope, $http) {
angular.element(document).ready(function () {
// This code attaches an event listener in jQuery (.click())
social.init();
});
});
});
EDIT: I am using includes as templating and it appears that the includes are getting fired AFTER the angular.element ready function. Which means it is not adding the event listener.

Related

Correctly binding multiple knockout viewmodels with Turbolinks?

Currently, the website I'm working on uses knockout for our frontend framework. I want to incorporate Turbolinks with multiple knockout viewmodels across different pages. The problem I'm running into is that since turbolinks doesn't actually change the page, bindings get applied multiple times which results in an error.
So far here is what I have tried.
I found this article which describes exactly what I want to do but doesn't necessarily work.
His solution is to replace the ko.applyBindings with
window.applyTurboBindings = function(node, viewModelAccessor) {
return $(document).one("page:change", function() {
return ko.applyBindings(viewModelAccessor(), node);
});
};
and use it with this
applyTurboBindings(document.getElementById('my-node'), function() {
return new MyViewModel();
});
page:change is no longer a method used with turbolinks according to their documentation. So I tried it using turbolinks:load (which fires once after the initial page load, and again after every Turbolinks visit) and turbolinks:visit (fires immediately after a visit starts). That wasn't working either. The event never gets triggered when I call the method applyTurboBindings so no bindings get applied.
Here is a fiddle with a basic setup of what I'm doing. fiddle
When I run this through my debugger, the applyTurboBindings never catches the event (turbolinks:load) that is firing.
One idea I had was to use something like this:
$(document).one("turbolinks:load", function () {
// execute all js for page here
});
instead of the typical
$(function(){
// execute all js for page here
});
But I couldn't get that working either because bindings were still getting applied multiple times.
So my question is how on earth do I get this working for multiple viewmodels so the bindings don't break? Should I be organizing my js differently? Is there a simple solution I'm not seeing or is this just not a good idea use both together?
This is my first question on Stack Overflow by the way so if I'm missing anything or I didn't make my question clear enough please let me know. Thanks for your help.

re-binding jquery selectors in angular

I have a very simple angular application that has one service which uses a http request to pull down a web page. I then want to display that page within my application using ng-bind-html.
template:
<div class="container" ng-bind-html="data"></div>
controller:
this.service.getHoliday().then(function(data) {
$scope.data = $sce.trustAsHtml(data);
});
this works from a visual perspective, however it would appear the javascript/jquery files are loaded but not used. I feel like this is because the elements are not available when it is run.
I feel like the best option to resolve this is to somehow rebind all the elements, is it possible to rebind the entire page without caring about each individual selector.
I've tried using a $apply() method, wrapping the above like so:
this.service.getHoliday().then(function(data) {
$scope.$apply(function() {
$scope.data = $sce.trustAsHtml(data);
});
});
but this stops the page from loading the html completely, i understand that this is vague but hopefully someone has come up against a similar issue that can help.

How does document.ready work with angular element directives?

In my current project I'm using angular directives to create custom html elements. See example below.
banner.js
app.directive('banner', function () {
return {
restrict: 'E',
replace: true,
templateUrl: './common/banner/banner.html'
};
});
Banner.html
<div>
<div class="banner-image"></div>
</div>
Issue: There is a javascript file that adds additional properties to elements with the banner-image class after document.ready. This worked perfectly before using angular element directives, but the properties are no longer being added.
Question: Does the document.ready callback occur prior to angular element directives being rendered in the dom? If so, that could explain why my javascript file is no longer making the necessary changes to the html elements.
Thank you
This is less a "directives" question, and more an Angular sequence of events question.
Angular itself (if not manually started with .bootstrap) will defer its loading until .onready.
At that point in time, Angular expects that all JS it needs to run will be there and registered.
Then Angular starts up.
Then after Angular starts up, Angular parses the DOM to find a root element to attach to (the one with the ng-app directive).
Then it recursively goes down the line, injecting controllers and building out directives and interpolating nodes as it goes.
Now we are way past any code that would have fired on DOMReady.

How can I get AngularJS binds working with a fancybox dialog?

I'm learning AngularJS and I'm having some difficulties with dialogs.
Since i'm converting my app from a classical Jquery-based to an angular one, i want to use Fancybox to open dialogs with custom dynamic HTML inside, with the fancybox open method.
$.fancybox.open(html);
I wrote a service to use fancybox: now i open my dialogs but the content inside the dialog is not "compiled" against angular, so any angular directive set on that HTML doesn't work.
See the example
http://plnkr.co/edit/UwryF1ocleyND7zxCGJz?p=preview
I imagine that the problem is in the service, but i don't know how to fix it. Could you show me how i can get an html sensible to angular directive inside the HTML shown in the dialog?
UPDATE:
i've tried to use $compile, and set a directive instead of a service (calling the method inside the directive directly from ng-click)
http://plnkr.co/edit/Y18bRSMdV62VObMGJ2Ie?p=preview
what's wrong now? why my $compile doesn't work as expected?
The problem is that angular looks for function expressions only on the scope and NOT on window as plain-javascript does. Hence, when you add an alert function on the $scope, it will be wired correctly: http://plnkr.co/edit/y02UMQ2kU4fh8Imsa82u?p=preview
$scope.alert = function (phone) { window.alert(phone.name); };

angularjs - After changing views using routing the jquery elements doesn`t get rendered

My issue is that after changing views using routing, the jquery components in my page doesn´t get rendered. I have customized ui components like dropdowns that are not being processed. I saw this answer: Angular.js App with routing.. Cannot get jquery ui layout plugin working on 2nd view
But I can´t figure out how to make it work in my case. It seems that when angular renders the template, any but angularjs code is processed.
Thanks so much in advance.
Code: http://plnkr.co/1mwMcsqMxWGTheoQmJ22
In the example you've provided, you're not actually loading the file with the jQuery code in it (jqcode.js).
The real problem however, as you can see in this version of your example, is that the document ready event is executed before your template has been loaded and rendered. This means that the element your jQuery code is attempting to target does't exist when you try to manipulate it.
You should really look into Angular directives which is where you are advised to place any DOM manipulation logic within an Angular project:
If you have to perform your own manual DOM manipulation, encapsulate
the presentation logic in directives.
From the Angular documentation for controllers.

Categories

Resources