(angularJS) make ng-click open a link on an ng-repeat - javascript

New to Angular, so sorry if this has been covered somewhere but it's hard for me to explain exactly what I want in succinct terms.
Currently I have an ng-repeat pulling data from a JSON object and making a list.
<li ng-click="openLink()" ng-repeat="location in locations">
{{location.name}}
</li>
Each object has a key called "link" and that key has a property that is a url. I want the function openLink() to open the link associated with each object. I'm not sure how to go about this in the controller.
I know i can do
<li ng-click="openLink()" ng-repeat="location in locations">
<a ng-href="{{location.link}}">{{location.name}}</a>
</li>
but i'd like to be able to do it with ng-click instead to keep the index.html cleaner. So what do I put in here to accomplish the same thing?
$scope.openLink = function() {
};

If the url that you want to redirect to is a route in your angular app, you need to inject the $location service into the controller, then in your function, set the path property on $location.
<li ng-click="openLink(location)" ng-repeat="location in locations">
{{location.name}}
</li>
$scope.openLink = function(location){
$location.path(location.link);
}
If the location link is a complete url, you should inject the $window service into your controller, and change the openLink function to set $window.location.href.
$scope.openLink = function(location){
$window.location.href = location.link;
}

Related

Trigger function on a certain element - ngrepeat - angularjs

Good morning,
I'm trying to change the limitTo filter on a certain list, my issue is:
when I click to the trigger who change the filter limit the filter changes on all ng-repeated categories.
my function inside the main controller
$scope.showMore = function(limit) {
if($scope.limitItems === $scope.itemsPerList) {
$scope.limitItems = limit;
$scope.switchFilterText = 'less';
} else {
$scope.switchFilterText = 'more';
$scope.limitItems = $scope.itemsPerList;
}
}
my scenario (I rewrote it in a simplified version)
<li ng-repeat="item in category.items | limitTo: limitItems ">
{{item.title}}
</li>
<li ng-if="limitItems < (category.items.length)">
<a ng-click="showMore(category.items.length)" >Show {{ switchFilterText }}</a>
</li>
Could you explain me what's wrong with me?
I searched how to select a single element to apply the function but I didn't find anything useful
Update:
I found the way to solve my issue in this way:
No functions inside the controller are involved to make this functionality works properly:
<li ng-repeat="category in maincategories" ng-init="limitItems = maxItemsPerList">
{{category.title}}
<ul>
<li ng-repeat="item in category.items | limitTo: limitItems "> {{item.title}}
</li>
</ul>
<a ng-click="limitItems = category.items.length" href>
<b ng-if="category.items.length > maxItemsPerList && limitItems != category.items.length "> Show more </b>
</a>
I'm not really convinced about Angular (I used it in my past and I was impressed by the performance but now I can see logics senseless):
What I learned:
ng-if and ng-click cannot be used in the same content because ng-if creates new scopes so if you put ng-if on top of the "show more" link it will break the code
ng-init cannot be used in the same element of the ng-repeat otherwise the var initialised will not be available inside the ng-repeat block
I think there is another way to do that, maybe more clean but in this specific case I can't do a lot.
ng-if and ng-click cannot be used in the same content because ng-if
creates new scopes so if you put ng-if on top of the "show more" link
it will break the code
Yes, ng-if creates a new scope, but it is possible to mix ng-if and ng-click (and most other directives). To do that, you'll be safer if you always write to atributes of another object instead of a simple variable. It is plain JavaScript prototypal inheritance in play.
<li ... ng-init="category.limitItems = maxItemsPerList">
ng-init cannot be used in the same element of the ng-repeat otherwise
the var initialised will not be available inside the ng-repeat block
True, in the sense that variables are created in the local scope. But again, refer to an object.
I think there is another way to do that, maybe more clean but in this
specific case I can't do a lot.
You don't need to do a lot, it is quite simple to do it right actually.
Some advices:
Use ng-init with care. I know it will tempt us but always try to put logic inside controllers and services;
Avoid assignments inside templates;
Learn how to use controllerAs syntax. It gives you an object to write your models to (the controller), so solves most problems related to scope inheritance;
Do not inject $scope, put your view models inside controllers.
Full code goes like this:
<li ng-repeat="category in maincategories" ng-init="category.limitItems = maxItemsPerList">
{{category.title}}
<ul>
<li ng-repeat="item in category.items | limitTo: category.limitItems "> {{item.title}}
</li>
</ul>
<a ng-if="category.items.length > maxItemsPerList && category.limitItems != category.items.length" ng-click="category.limitItems = category.items.length" href>
<b> Show more </b>
</a>

Dynamically generated navbar and AngularJS

I could not find an easy way to explain the following, so I apologize if it is not clear enough.
I have a navigation bar where each item is a category of articles. The navigation item are read from database and can be modified from the back-office.
I get the categories via a AngularJS controller :
app.controller('ApiController', ['$scope', '$http', function($scope, $http) {
$http.get('/categories')
.success(function(categories) {
$scope.categories = categories;
});
}]);
<div class="collapse navbar-collapse" id="target-navbar-main">
<ul class="nav navbar-nav">
<li ng-repeat="category in categories">
<% category.name %>
</li>
</ul>
</div>
In the body of the page, I am using another controller to get articles of a given category but I can't find a way to make the navbar communicate with the articles controller and pass the category of the clicked button.
Thanks for help
I think what you want for the API is a service not a controller. Generally in Angular controllers aren't meant to be sending a bunch of data between each other. Central sets of calls and communications that multiple controllers depend on are put into services. If you were to extract your API calls to a service you could inject that service into that controllers that need to deal with it as necessary. But without seeing more of the code in question it's hard to recommend a good way to do that.

Binding external URL in angularjs template

I have a angularjs app with a controller and a partial wired up..
In my controller I have a array of links..
$scope.links = ['http://www.example.com/1','http://www.example.com/2'];
In my partial, I have the following code..
<div ng-repeat="link in links">
Link
</div>
This does not seem to work.. I am running this via a NodeJS app locally..and so my URLs always end up as
http://dev-server.local:3000/"http://www.example.com"
Can anyone please help me figure out how I can add a hyperlink from my controller directly into my partial template and make Angular not append the page URL..
You have to explicitly trust extern URL:s. Look at the documentation for $sce.
In you controller, make sure you have a dependency to $sce, then in create a method that trust the external url.
$scope.trustUrl = function(url) {
return $sce.trustAsResourceUrl(url);
}
In your view you can reference this method and pass in the url with
<a ng-href="{{ trustUrl(item) }}">Click me!</a>
instead of
href={{link}}
use
ng-href={{link}}

How to setup ngclass change when route change occurs in AngularJS?

I am trying to add a class on my main .container class when the route changes.
My current simple solution involves an ng-click on every main menu url (no other urls on the page):
app.controller('MainCtrl', ['$scope', function( $scope ){
$scope.setMain = function( value ){ $scope.isMain = value };
}]);
Then in my html:
<div ng-controller="MainCtrl" class="container" ng-class="{'main': isMain}">
<ul class="main-menu">
<li><a href="#" ng-click="setMain(true)"></li>
<li><a href="#/page-1" ng-click="setMain(false)"></li>
<li><a href="#/page-2" ng-click="setMain(false)"></li>
</ul>
<div ng-view></div>
</div>
This seems to work ok as long as I need to add any more urls the problem is when a user does not click on any of the links and directly accesses a url he does not get the main class.
Is there a better way to do this?
You could use a few different options, but I think the easiest for you would be to setup the $scope.isMain value on controller initialisation by looking at $location. So inside the controller you could have something like:
var loc = $location.path();
if(loc === /* some route rule you require */){
$scope.isMain = true;
}
Have a look here: http://docs.angularjs.org/api/ngRoute/service/$route as the example down the bottom has a few different examples of what sort of data you can access with regards to the route.

Go to the specific url on clicking of a div in angularjs

I am developing an angular mobile APP, where i wanted to go tho the specific url for eg: www.google.com on clicking of a particular div. but i am not able to do that as i am new to this angular world.
<div ng-click="goToGoogle('www.google.com');" class="" id="">
<p class=""><span class="">Go to Google Full Web Site</span></p>
</div>
In controller Function
$scope.goToGoogle = function (url) {
$scope.$apply( $location.path(url) );
}
Please help me to do that.Thanks in advance for any help.
In your controller, have you passed in the $location service along with the scope?
UPDATE
Try passing the $window service.
$window.location.href = url;
You don't even have to use $scope.apply for it.

Categories

Resources