Unable to scroll to a div element using hash in Angular app - javascript

I have read here and here that a page can be scrolled to a specific element using just a hash selector and a id attr.
But for some reasons I am unable to do it in my Angular application. Can this be due to the usage of routing (angular-ui-router) in my app.
What I am trying to do is moving to a specific section of one of my page, which by the way are loaded in to a state using routing.
I have :
<div class="nav_panel">
<a class="nav_links" href="#footer">Footer</a>
</div>
and
<div class="homeFooter" id="footer">
<div class="social_icons">
<span class="gplus"></span>
<span class="fb"></span>
<span class="twitter"></span>
<span class="whatsapp"></span>
<span class="youtube"></span>
</div>
</div>
on the same template.
Is there a way I can make it work with routing (if at all that matters) as well or am I doing something wrong here ?

Based on this answer, you can add the _targetattribute to the <a>tag.
For your need, value on _target is self. It's an attribute compatible with all recent browser, that will redirect you to the link in the same frame as the user click (useful for SPA e.g.)
Go to the footer
<div id="footer">Welcome to the footer</div>

Related

Trying to open a site in new tab in Angular but not working

I have a simple situation and I thought it will be resolved easily. But got stuck.
I have a header component. There are two situations here:
Before login, the text in header component will be "LOGIN" and it will be clickable. On click, it will take me to another external url (lets assume https://www.external.com).
After login, the same header component but text will be "LOGGED IN" and it won't be clickable.
WHAT I TRIED
HTML File (header.html)
<div class="brand pull-left" (click)="onHeaderClick()">
<div class="logo"></div>
<h1>{{headerText}}</h1>
</div>
Typescript File (header.ts)
onHeaderClick() {
debugger;
if(!this.isLoggedIn) {
window.open('https://www.external.com', '_blank');
}
}
But, its not redirecting me to the specified url and not also opening a new tab.
Its just refreshing the same page.
Can anybody please help me out with any solution and also if it can be explained why its not working.
Thanks.
You should handle the logic of if it's clickable in the Template and not in the TS-logic.
Also don't use divs for onclick events, use buttons or links (in your case this is a link!). You can focus them with the keyboard and also click them with pressing spacebar while it's focused. If you use the semantically correct tag you won't have problems opening it in a new window.
Something like this:
<ng-template #contentTemplate>
<div class="logo"></div>
<h1>{{headerText}}</h1>
</ng-template>
<div *ngIf="!loggedIn; else loggedInBlock">
<a class="brand pull-left" href="https://www.example.com" target="_blank" >
<ng-container [ngTemplateOutlet]="contentTemplate">
</ng-container>
</a>
</div>
<ng-template #loggedInBlock>
<ng-container [ngTemplateOutlet]="contentTemplate">
</ng-container>
</ng-template>
And in your .ts file you have a boolean variable named loggedIn If you are logged in this is set to true, otherwise it's set to false.
If you have the same content in both containers, you can either create it's own component for this (and then just use something like app-header-content instead of the ng-container or you use, as I did in the example above, use a template.
Check Angular documentation for other ways to implement if-else logic

Angular does not work with custom html attributes

I have an imported css template written on bootstrap, and want to use it inside Angular app.
Seems like exactly custom html attributes don't react a loading from router.
Application characteristics. This is a SPA, and all of pages are loaded inside Navbar Component, with corresponding router-outlet wrapping.
Problem. Any plugin will render included data only after "mechanical" refreshing page with browser "Reload this page" button. But if I change a src for image, from plugin custom attribute, for example
data-background="assets/images/slider_1.jpg"
to
img src="assets/images/slider_1.jpg"
, it will be loaded and shown from the first time.
Example of map plugin. Doesnt show nothing.
<div class="maps-container map-widget m-b-25">
<div class="map" data-addresses="[4.4, -4.4]"
data-icon="assets/images/map-marker.png"
data-zoom="16" data-street-view="1">
</div>
</div>
Example of slider plugin. No background image.
<section class="module-cover parallax text-center"
data-background="assets/images/slider_1.jpg"
data-overlay="0.5">
<div class="container">
<div class="row">
<div class="col-lg-12">
<h1>This is title</h1>
</div>
</div>
</section>
Example of grid item for blog. Here, it should follow masonry style, but renders like strict grid.
<section class="module-cover parallax text-center"
data-background="assets/images/slider_1.jpg"
data-overlay="0.5">
You better use [attr.data]="name-of-custom-attr"
This way angular manages the use of custom html attributes correctly.

website gets slow when huge amount of data is being loaded

I have a internal team website build using python django and angularJS. The website works fine when there is low data/ content on it.
When the website gets scrolled and more data is loaded. It becomes slow.
The major problem occurs when we try to open any modal or try to write text in the textarea. The text lags while writing and modal open very slowly.
I have used nested ng-repeat there are 5 nested ng-repeat.
<div ng-repeat="x in xyz">
<div ng-repeat="y in xyz">
</div>
<div ng-repeat="img in xyz">
</div>
<div ng-repeat="y in xyz">
<div ng-repeat="z in xyz">
</div>
</div>
</div>
Above is the example of the structure being used in the website.
The above snippet repeat itself around 100 times thorughout the page.
These are having images, forms, text, input , user tagging like facebook.
ngCacheBuster,ui.bootstrap, ngTagsInput, ui.mention,monospaced.elastic these are the external library being used in the website.
the website is built using bootstrap.
Is there a specific reason why the website becomes heavy.
each size of the image is around 100kb on an average.
really? the page loads slow when there is alot of data? :D
anyway the most simple method to speed-up heavy data apps is to conditionally load and render parts of it, for example:
<div ng-repeat="x in bla" ng-click="showL1 = true">
<div ng-repeat="y in boo" ng-if="showL1 === true">
//more...
</div>
</div>
on the other part is double check your architecture, since there is a very limited amount of data a person can take from a page and therefor start thinking about tabs and paging
Maybe u need use some function in your controller that will load some part of all data for user.
For example:
app.constant('range' , 10);
app.controller('example', ['$scope', function($scope) {
$scope.loadRangeData = function(range) {
//your way of loading data with using range
}
}
]);
and after u can use ng-repeat as
<div ng-repeat="x in loadRangeData">
but best way it's finding answer in your django maybe

Angular template text in Safari on backwards navigation

I'm working on an Angular app that makes a call to a data service and then repeats the results in the view. Each result has a unique, external link. I've found that, in Safari, when you click the link and then navigate backwards with the browser button, you see only the bracketed Angular template text. So,
<div ng-repeat="i in items">
<div>{{i.name}}</div>
<div>{{i.location}}</div>
<div>{{i.link_name}}</div>
</div>
yields
{{i.name}}
{{i.location}}
{{i.link_name}}
with the anchor being just an empty link. This phenomenon does not appear in Chrome. The app is being served by Rails.
That is basically uncompiled html by angular shown on HTML. In that case I'd prefer you to use ng-bind directive to html on page.
<div ng-repeat="i in items">
<div ng-bind="i.name"></div>
<div ng-bind="i.location">{{i.}}</div>
<div><a ng-href="{{i.link}}" ng-bind="i.link_name"></a></div>
</div>

Multiple partial views on AngularJS

I have an AngularJS application that has a list of contents on the menu. When the user clicks on an item on the menu, the content loads on the main view. There are multiple content types:
When "1" is clicked, a video is loaded. When "2" is clicked, a PDF document is loaded, and so on. Content types may repeat and be complex.
Now, I am setting $scope.content when an item is clicked and, depending on its contentType, I'm calling a different directive:
<div class="content" ng-switch on="content.contentType">
<div ng-switch-when="video">
<videoplayer-directive video="content"></videoplayer-directive>
</div>
<div ng-switch-when="pdf">
<pdfreader-directive pdf="content"></pdfreader-directive>
</div>
<div ng-switch-when="...">
<...-directive content="content"></...-directive>
</div>
</div>
Now I have two problems:
When the page is loaded, all the directive templates are automatically loaded. Even if I don't have a PDF in the menu, the pdf template and scripts will be loaded.
Searching for it, I learned that directives should be tiny, not entire modules of my app.
How do I rewrite the switch above so I can comply with the best practices and load the templates and scripts only when needed?
This is exactly what UI-Router is for: Angular UI Router
Decent tutorial on scotch.io
An easier drop-in replacement for your code may be to simply use ng-if. Ng-if won't instantiate the directive until it's called. Just make sure that your directives aren't transcluding the outer div- if that's the case, shut transclusion off, or add another div to wrap them.
<div class="content">
<div ng-if="content.contentType=='video'">
<videoplayer-directive video="content"></videoplayer-directive>
</div>
<div ng-if="content.contentType=='pdf'">
<pdfreader-directive pdf="content"></pdfreader-directive>
</div>
<div ng-if="content.contentType=='...'">
<...-directive content="content"></...-directive>
</div>
</div>

Categories