I'm trying to remove jquery from my Angular.js app in order to make it lighter, and put Angular's jqLite instead. But the app makes heavy use of find('#id') and find ('.classname'), which are not supported by jqLite, only 'tag names' (as per documentation)
wondered what do u feel would be the best approach to change it. One approach I thought about is to create custom HTML tags. for example:
change
<span class="btn btn-large" id="add-to-bag">Add to bag</span>
to
<a2b style="display:none;"><span class="btn btn-large" >Add to bag</span></a2b>
and
$element.find('#add-to-bag')
to
$element.find('a2b')
Any thoughts? other ideas?
thanks
Lior
Essentially, and as-noted by #kevin-b:
// find('#id')
angular.element(document.querySelector('#id'))
//find('.classname'), assumes you already have the starting elem to search from
angular.element(elem.querySelector('.classname'))
Note: If you're looking to do this from your controllers you may want to have a look at the "Using Controllers Correctly" section in the developers guide and refactor your presentation logic into appropriate directives (such as <a2b ...>).
angualr uses the lighter version of jquery called as jqlite which means it doesnt have all the features of jQuery. here is a reference in angularjs docs about what you can use from jquery.
Angular Element docs
In your case you need to find a div with ID or class name.
for class name you can use
var elems =$element.find('div') //returns all the div's in the $elements
angular.forEach(elems,function(v,k)){
if(angular.element(v).hasClass('class-name')){
console.log(angular.element(v));
}}
or you can use much simpler way by query selector
angular.element(document.querySelector('#id'))
angular.element(elem.querySelector('.classname'))
it is not as flexible as jQuery but what
If elem.find() is not working for you, check that you are including JQuery script before angular script....
Related
I would need to add an autocomplete chips component in our Angular 1.6 application. We are using Typescript, Webpack 2. As we are already using angular-ui-bootstrap, we do not want to introduce also angular-material in order to avoid style conflicts. However the wished result is exactly what material chips provide.
Is there a directive or component that i can use in my case? I found this library but it runs endless exceptions when I import it.
unfortunately I could find only partial solutions with bootstrap typehead, but then I would need to implement all the "chips" part, making me think of re-inventing the wheel.
Stack Newb here. I have an identical problem as yours. Here's how I resolved this:
1. Resolve the ReferenceError: error is not defined within the angular-chips library
The library you used (angular-chips) wasn't designed with typescript in mind. So, you'll first need to resolve the following error ReferenceError: error is not defined by defining it for them in the line above with var error;. This should prepare angular-chips for your webpack useage.
The second issue you'll find is how to add your typeahead-template-url with webpack in the mix. Rather than referring to a separate html file, use an inline template as referenced here: Bootstrap-UI Typeahead display more than one property in results list?.
If you're lazy like me and don't want to follow that hyperlink, use this as example:
2. Template to be added before the <chips> tag:
<script type="text/ng-template" id="yourTemplate.html">
<a tabindex="-1">
<i ng-class="'icon-'+match.model.type"></i>
<span ng-bind-html-unsafe="match.model.title | typeaheadHighlight:query"></span>
</a>
</scrip>
3. Include template in your directive:
typeahead-template-url:"yourTemplate.html"
Worked like a charm for me.
What's the best way to create a dynamic slideshow using angular 1.3? I would like to build one, I was trying with http://jquery.malsup.com/cycle2/ but it doesn't work when use angular.js at the same page.
<div ng-repeat="diaporama in diaporamas" class="cycle-slideshow">
<img class="diaporama-img" src='{{diaporama.photo_file_name | image_diaporama_path_format: diaporama.id}}'/>
</div>
<script>
$(".cycle-slideshow").cycle();
</script>
I believe in order to achieve what you desire you'll be looking to create a directive for that purpose.
A good start would be referring to angulars documentation on directives.
Hope that helps!
I am going to create an application with Angularjs. I have several modals (with the ng-dialog libraries) to create, modify data like an user for example.
When I open it, I can always see during several milliseconds names variables with accolades like {{user.name}}, before it renders the real value.
It is not really beautiful and then if someone has an idea about how to manage this type of display problems, please share it.
Thank you in advance.
There are couple of ways to deal with it, you could either use ng-bind or ng-cloak directives
Check angular ngCloak directive documentation
https://docs.angularjs.org/api/ng/directive/ngCloak
You can use ng-bind. Here is the official documentation on it:
It is preferable to use ngBind instead of {{ expression }} if a template is momentarily displayed >by the browser in its raw state before Angular compiles it. Since ngBind is an element attribute, >it makes the bindings invisible to the user while the page is loading
Usage:
Hello <span ng-bind="name"></span>!
I have a few bits of HTML like
<p class="noresults">{{numberOfContacts}} Results Are Available</p>
Is it possible for me to hide {{numberOfContacts}} until Angular has loaded? So it would just say Results Are Available
I've seem some solutions such as hiding the entire body until Angular has loaded, but I'd rather not do that if possible.
Yes, use ng-cloak. Simply add class="ng-cloak" or ng-cloak to an element like this
Using directive <div ng-cloak></div>
Using class <div class="ng-cloak"></div>
It's simply a set of CSS rules with display: none !important and as Angular has rendered your DOM it removes the ng-cloak so an element is visible.
use <span ng-bind="numberOfContacts" /> instead of {{numberOfContacts}}
Sometimes, even if I used the ng-cloak, I could still see the braces for a few seconds. Adding the following style resolved my issue:
[ng-cloak]
{
display: none !important;
}
Please see this link link for more explanation.
Hope it helps :D
This is typically only an issue when working with complex content on really slow devices. In those instances, there can be a brief moment when the browser displays the HTML in the document while AngularJS is parsing the HTML, getting ready, and processing the directives. In this interval of time, any inline template expressions you have defined will be visible to the user. Most devices nowadays have pretty good browsers which are quick enough to prevent this from being an issue. There are two ways to solve the problem.
Avoid using inline template expressions and stick with ng-bind directive.
(Best) Use the ng-cloak directive which will hide the content until Angular has finished processing it. Basically, the ng-cloak directive uses CSS to hide the elements and angular removes the CSS class when the content has been processed, ensuring that the user never sees the {{ and }} characters of a template expression.
One strategy to consider is using the ng-cloak directly to the body element, which will ensure that the user will see an empty browser while AngularJS loads. However, you can be more specific by applying it to parts of the document where there are inline expressions.
I have seen issues with ng-cloak not working when added to an element. In the past, I have worked around this issue by simply adding ng-cloak class to element.
You can use ng-bind instead of expression like
<span ng-bind="data"></span>
I'm trying to work out why this doesn't work:
<a class="ng-click: loadSomeDatas();">Click here to load some datas</a>
But this does:
<a ng-click="loadSomeDatas()">Click here to load some datas</a>
Why are you using classes?
Well ng-* attributes don't play nice on some of the clients I have to support, thus rather than shimming them I'd rather just use good ol' safe classes.
This looks like a documentation error. According to the source code, it can only be used as an attribute. The link function does not use restrict so the default is "attribute only".
Can you try using "data-ng-click"? Angular will still work with data- appended before it's attribute names and this should be valid syntax in older browsers.
<a data-ng-click="loadSomeDatas()" href="#">Click here to load some datas</a>