I'm really sorry if this has already been answered, but I have no idea how to search for it since it seems so specific.
I've got an AngularJS app using ui-router to dynamically load multiple views into the same <ui-view> element. I want to use Jquery UI's tooltip function on one of the h3 elements loaded dynamically by ui-router, but I don't know where to put the initializer such that it runs after the h3 is in the DOM.
Things I've tried:
Embedding a <script> tag in the HTML partial that calls $("h3").tooltip()
Putting the script tag in the main parent HTML template - with and without a document.ready wrapper
Putting the tooltip() function call in one of the angular js files that's loading the partial (when I changed the line to just alert(), it seemed that this code was running right before the partial is rendered, so there are no <h3>s yet)
I'm very confused as to how I can run arbitrary javascript code on dynamically loaded elements ... I think the first method should have worked. Even when I make the <script> tag just contain a simple alert(), nothing happens.
Any ideas? I'm also happy to provide more information, but I think I can't show the actual code due to an NDA.
may these will help you:
Embed javascript in angular ui-router view
AngularJS: How to make angular load script inside ng-include?
The approach you are taking to get that tooltip working is very wrong. Instead of trying to load a script dynamically inside a view, you should be wrapping the tooltip plugin inside a directive and assigning that directive to your h3 element. Or, even simpler, use Angular UI Bootstrap's Tooltip directive: http://angular-ui.github.io/bootstrap/
Mock code for custom directive:
'use strict';
angular.module('MyModule')
.directive('tooltip', function () {
return {
restrict: 'A',
link: function(scope, element, attrs) {
// initialize jQuery tooltip
// note element is a jqLite object with jQuery methods available
// DO NOT ATTEMPT TO WRAP element WITH jQuery
// ANGULAR CANNOT TRACK jQuery OBJECTS THAT
// ARE NOT WRAPPED WITH jqLite!!!
element.tooltip(...);
}
};
});
Related
Before learning AngularJS I learned jQuery ( + mustache for templates). Now It is difficult to understand how to work with AngularJS...
I am trying to show modal window for user. Early (jQuery) I created a template, parsed it and appended it to the DOM.
In AngularJS, if I understand correctly, there are more than one way to do it. I can use ngView directive, ngInclude directive, ngBingHtml directive, create custom directive with 'templateUrl', and may be something else...
But I dont want to load templates from server on demand, I want to create script section with type='text/ng-template' and use it.
First of all I cant understand what the right way to choose, second is how dynamicly change templates (I need put template into directive, work with template, delete template, but not directive... yes?)
Thank a lot.
I have a list of posts which loads perfect, the entire content of each post. The html post content is a string in database column. Now I want to create a read more link at the position that I desire and only show a post preview in the list (a part of the html content). To accomplish that I write a comment inside the posts it´s the point to cut the content in order to preview.
How can I manipulate the content before the ng-bind-html loads it? I need to detect the first comment and clean the content html document. I´m making tests in jquery but i would like to know how to do it on the angular way.
I think that a filter inside the ng-bind-html expression can do the work. But i don´t now how to manipulate the html string inside the filter. Manipulate like jquery syntax because i need to remove a lot of tags and do some stuff.
<script>
$(function() {
var com = $("*")
.contents()
.filter(function(){ return this.nodeType == 8;})
.first();
com.nextAll().remove();
});
</script>
Thanks
You can add a function that will be executed during ng-bind-html and get access to your string by using sanitise service $sce. See the details on $sanitise service.
Inside the ng-bind-html you can manipulate the DOM using jqlite and native javascript (by using $document wrapper). If the manipulations are too complex, I'd use jquery directly. To do that you have to just include it before angular in your index.html and use angular.element instead of $
I'm building a third party widget that will be loaded onto multiple sites. I'm using angular for implementation, with a build script that wraps my angular so it doesn't interfere with any other angular that might be used on the page.
Everything works fine when I use my own custom directives, but when I tried to incorporate a loading indicator, using ng-show, it "sometimes" didn't work. I tracked the "sometimes" down to "on pages that already use angular".
It seems that the page's angular is still data binding my templates when they are inserted into the page. Is there any way I can make my dom a no-go zone for the page's angular?
ng-non-bindable seemed like it might work, but if I use that, I can't bootstrap underneath it.
What you need to do is to bootstrap angular programatically instead of using a tag.
<html>
<body>
// other parts of your site
<div></div>
// your angular stuff
<div id='app' ng-controller="MyController">
Hello {{greetMe}}!
</div>
</body>
</html>
// your controller
angular.module('myApp', [])
.controller('MyController', ['$scope', function ($scope) {
$scope.greetMe = 'World';
}]);
// bootstrap angular programatically/manually
angular.element('#id').ready(function() {
angular.bootstrap(angular.element('#id'), ['myApp']);
});
Without forgetting to use ng-non-bindable too on parts that u don't want to bind ofcoz
So, here is what I have done, which is an abomination. I would much prefer a clean answer, but this protects my dom from the other angular instance.
First, I wrap my entire dom element with ng-non-bindable. This keeps the page-level angular from interfering with it.
Then, I add the following, adapted from AngularJS - how to override directive ngClick
var root = angular.module('rootModule', []);
root.config(function($provide){
$provide.decorator('ngNonBindableDirective',
['$delegate', function($delegate){
$delegate.shift();
return $delegate;
}]);
});
This removes the implementation of ng-non-bindable inside my angular instance. So the page angular will ignore the dom, but my angular won't ignore it. I just hope I don't have to implement ng-non-bindable-really later down the line.
Someone please save me from this horror by giving me a clean answer!
I'm working with AngularJS.
One of the (technical) requirements is to fetch the "ng enabled" HTML content from the server, in response to a click event, and inject it into a <div ng-app> via JavaScript.
The problem is that the newly injected HTML is not wired, as Angular goes through the compile and link phases only when the page is loaded the first time.
Is there a way to trigger them manually?
Am I approaching this problem in the wrong way? Is there a more idiomatic way to accomplish what I described?
Thanks
There are multiple ways to inject dynamic content into the view in AngularJS. One of the way to inject dynamic content is to use ng-include directive. It can take an endpoint from where to get view.
You can combine it with ng-if to achieve load view on click. For example:
<span ng-if="clicked">
<div ng-include='pathToTheHtml'></div>
</span>
The clicked variable would be false first, on clicking on the button set it to true, this would trigger ng-include to get the content and inject it into html.
If you want finer control then you need to use the $compile service. The html that needs to be injected into the DOM needs to be compiled and linked to the scope using $compile service. This can be done in a directive.
element.append($compile(htmlFragment)(scope))
angular.bootstrap(element, [modules], [config]);
Quote from one of the comments regarding ngCloak directive (AngularJS documentation):
It is only really needed on your "index.html" page, because the
browser may try to render things before Angular has had a chance to
parse/compile it. At runtime, when Angular pulls in content due to
ng-view, ng-include, etc., it will be processed by Angular before the
browser renders.
I created a example in jsFiddle to verify this and on my surprise the expression is not evaluated before it is rendered in the browser. I would expect that the template will first be compiled & linked and then attached to the DOM - which is not the case.
Does that mean that every {{expression}} inside templates should also be wrapped in ngCloak to prevent flickering or am I missing something?
My guess is that the alert allow the browser to render before angular finished his job, adding a setTimeout with 0 delay show a rendered template:
http://jsfiddle.net/g/FLZZR/5/
function TemplateController ($scope) {
$scope.expression = "This should already be rendered...";
setTimeout(function(){
alert("... but it isn't.");
});
}
Additional note: you can't expect the template to be rendered at the point you place your alert, at best it would be hidden, angular use dirty checking to do its magic and you must let it "digest" your changes for them to show in the DOM.