I'm dynamically loading templates which is working fine. Now my concern is I need to add a JavaScript logic to template
I need to use something like this in my template.
{{ var entries = 0; }}
{{ for(var r = 0; r < d; r++) }}
Suppose my template returns this HTML
<div ng-repeat="x in names" ><span>{{x.name}}</span>{{some logic here which is plain js. var a=[] if(a=b){}}}</div>
My question is how to achieve this.
<div ng-repeat="entry in entries track by $index">
{{entry}},{{$index}}
</div>
Use ng-repeat.
<div ng-repeat="entry in entries">
{{entry}}
</div>
If you need the index:
<div ng-repeat="entry in entries">
{{entry}},{{$index}}
</div>
Docs: https://docs.angularjs.org/api/ng/directive/ngRepeat
<div ng-init="entries[0,1,2,3,4]">//Use ng-int to initialize data
<div ng-repeat="data in entries">// use ng-repeat to loop over
{{data}}
</div>
</div>
Related
I would like to create dynamically 3 input tags in Angular 6 to not copy/paste html code because that input elements have similar html and functionality.
For this purpose I created an array "reusableItems" inside component and initialize it :
let numberOfInputElements = 3;
for (let i = 0; i < numberOfInputElements; i++) {
this.reusableItems.push({
answer: 'Answer ' + (i +1),
passwordRecoveryAnswer: this.user['passwordRecoveryAnswer' + (i + 1)]
});
}
Then I put code inside my html :
<div *ngFor="let item of dropDownDataManagerService.reusableItems" >
<li class="col-xs-12 pl-lg pr0 pv-sm bd1-bottom">
<div class="col-xs-4 ph0 pt"> {{item.answerTitle}}</div>
<div class="col-xs-8">
<input type="text" name={{item.answer}} ref-{{item.answer}}="ngModel" class="col-sm-12 k-textbox ph0"
[(ngModel)]=item.passwordRecoveryAnswer
[pattern]="[a-z]"
required autocomplete="off"/>
</div>
</li>
</div>
It seems works fine but then I need to add error messages when these fields will be empty and not match to pattern. Something like :
<div *ngIf="__{{item.answer}}__.errors?.required ">
{{'Please provide an answer' | translate}}
</div>
<div *ngIf="__{{item.answer}}__.errors?.pattern">
{{'Pattern is not match'}}
</div>
I don't know what should i put inside ngIf condition.
How can I do it if my template reference variables are comes from array?
Is anyone have ideas?
Thanks
Angular creates unique template reference variable for each embedded template so that you can use the same template reference variable name inside ngFor loop:
<div *ngFor="let item of reusableItems">
<li class="col-xs-12 pl-lg pr0 pv-sm bd1-bottom">
<div class="col-xs-4 ph0 pt"> {{item.answerTitle}}</div>
<div class="col-xs-8">
<input type="text" name={{item.answer}} ref-answer="ngModel" class="col-sm-12 k-textbox ph0" [(ngModel)]="item.passwordRecoveryAnswer"
[pattern]="'[a-z]'" required autocomplete="off" />
<div *ngIf="answer.errors?.required">
{{'Please provide an answer'}}
</div>
<div *ngIf="answer.errors?.pattern">
{{'Pattern is not match'}}
</div>
</div>
</li>
</div>
In the code above I use the same name for each input in array
ref-answer="ngModel" // or you can also use #answer="ngModel
So I have a nested ng-repeat like so:
<div ng-repeat="data in flow" ng-init="$flowIndex = $index">
Index: {{ $index }}
<div ng-click="flow.splice($index, 1)">Delete me</div>
<div ng-repeat="inside_data in flow[$flowIndex]">
Inside index: {{ $index }}
</div>
</div>
I want to be able to delete index in my $flowIndex. However if I have something like this:
0
1
2
3
And I delete index 2. If I go and delete index 3, it isn't found because ng-init variable still things its at index 3 but really its not at index 2.
Does anyone know a work around?
You can get rid of $flowIndex, it's not necessary, you can use $parent.$index instead, when you are using ngRepeat it creates a child scope and $index is part of that scope. Also consider moving your deleting logic into the controller.
Controller:
$scope.delete = function ($index) {
$scope.flow.splice($index, 1);
};
Html:
<div ng-repeat="data in flow">
Index: {{ $index }}
<div ng-click="delete($index)">Delete me</div>
<div ng-repeat="inside_data in flow[$index]">
Inside index: {{ $parent.$index }} -> {{ $index }}
</div>
</div>
I believe you can get the parent index like so:
$parent.$index
As mentioned in this answer: passing 2 $index values within nested ng-repeat
That way you don't have to worry about your variable being out of sync with your current state.
I just tested your similar code with some dummy data strings and the delete appears to work. I made some updates to your code to better analyze it.
// Code goes here
var myApp = angular.module('myApp',[]);
myApp.controller('MyController', ['$scope', function($scope) {
$scope.flow = [
["test01","test02","test03"],
["test11","test12","test13"],
["test21","test22","test23"],
["test31","test32","test33"],
["test41","test42","test43"]
]
;
}]);
<!DOCTYPE html>
<html>
<head>
<script data-require="angularjs#1.5.8" data-semver="1.5.8" src="//opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="myApp">
<section ng-controller="MyController">
<div ng-repeat="data in flow">
Index: {{ $index }}
<div ng-click="flow.splice($index, 1)">Delete me [{{ $index }}]</div>
<div ng-repeat="inside_data in flow[$index]">
Inside index: {{ $index }} : {{ inside_data }}
</div>
<hr>
</div>
</section>
</body>
</html>
Hello I am a new in angular js. I want to count in ng-repeat like this :
<div ng-repeat="people in peoples">
{{ numberPeople++ }}. {{people.name}}
<div ng-repeat="repeople in people.families">
{{ numberPeople++ }}. {{repeople.name}}
</div>
</div>
<div ng-repeat="otherpeople in otherpeoples">
{{ numberPeople++ }}. {{otherpeople.name}}
</div>
{{ numberPeople }}
</div>
numberPepple will increase in each ng-repeat
I see many question they said use $index but i use many ng-repeat
You can use ng-init.
Tyr this:
<div ng-repeat="people in peoples" ng-init="numberPeople=numberPeople+1">
{{ numberPeople }}. {{people.name}}
<div ng-repeat="repeople in people.families" ng-init="numberPeople=numberPeople+1">
{{ numberPeople }}. {{repeople.name}}
</div>
</div>
<div ng-repeat="otherpeople in otherpeoples" ng-init="numberPeople=numberPeople+1">
{{ numberPeople }}. {{otherpeople.name}}
</div>
{{ numberPeople }}
</div>
You can use angular.forEach in JS file and set it in the model. Use that model in the HTML code.
I'm guessing the ++ is not working, in your controller add $scope.numberPeople = 0; at the top and it will initialize the scope variable as an integer type and assign 0 to it. Then you can use ++.
I have a an array of objects like this in angular:
$scope.data = [
{name:"John", group:"a"},
{name:"David", group:"a"},
{name:"Tom", group:"b"},
];
I want to present this data as something like this (in a template):
<h2>group a</h2>
John<br/>
David<br/>
<h2>groub b</h2>
Tom<br>
How would you suggest to do this? How can I go from the structure at the beginning to the structure at the end?
You could use grouby filter that would do group for you on basis of group property
Markup
<div ng-repeat="(key, value) in data | groupBy: 'group'">
<h1>group {{ key }}</h1>
<div ng-repeat="person in value">
{{ person.name }}
</div>
</div>
I am trying to display a binary tree of elements, which I go through recursively with ng-include.
What is the difference between ng-init="item = item.left" and ng-repeat="item in item.left" ?
In this example it behaves exactly the same, but I use similiar code in a project and there it behaves differently. I suppose it's because of Angular scopes.
Maybe I shouldn't use ng-if, please explain me how to do it better.
The pane.html is:
<div ng-if="!isArray(item.left)">
<div ng-repeat="item in [item.left]" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.left)">
{{item.left[0]}}
</div>
<div ng-if="!isArray(item.right)">
<div ng-repeat="item in [item.right]" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.right)">
{{item.right[0]}}
</div>
<div ng-if="!isArray(item.left)">
<div ng-init = "item = item.left" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.left)">
{{item.left[0]}}
</div>
<div ng-if="!isArray(item.right)">
<div ng-init="item = item.right" ng-include="'Views/pane.html'">
</div>
</div>
<div ng-if="isArray(item.right)">
{{item.right[0]}}
</div>
The controller is:
var app = angular.module('mycontrollers', []);
app.controller('MainCtrl', function ($scope) {
$scope.tree = {
left: {
left: ["leftleft"],
right: {
left: ["leftrightleft"],
right: ["leftrightright"]
}
},
right: {
left: ["rightleft"],
right: ["rightright"]
}
};
$scope.isArray = function (item) {
return Array.isArray(item);
}
});
EDIT:
First I run into the problem that the directive ng-repeat has a greater priority than ng-if. I tried to combine them, which failed. IMO it's strange that ng-repeat dominates ng-if.
It's a little hacky, but I am passing variables to an ng-include with an ng-repeat of an array containing a JSON object :
<div ng-repeat="pass in [{'text':'hello'}]" ng-include="'includepage.html'"></div>
In your include page you can access your variable like this:
<p>{{pass.text}}</p>
Pass parameter to Angular ng-include
You don't need that. all ng-include's sources have the same controller. So each view sees the same data.
What is the difference between ng-init="item = item.left" and ng-repeat="item in item.left"
[1]
ng-init="item = item.left" means - creating new instance named item that equals to item.left. In other words you achieve the same by writing in controller:
$scope.item = $scope.item.left
[2]
ng-repeat="item in item.left" means create list of scopes based on item.left array. You should know that each item in ng-repeat has its private scope
I am trying to display a binary tree of elements, which I go through recursively with ng-include.
I posted in the past answer how to display tree by using ng-include.
It might helpful: how-do-display-a-collapsible-tree
The main part here that you create Node with id wrapped by <scipt> tag and use ng-repeat:
<script type="text/ng-template" id="tree_item_renderer">
<ul class="some" ng-show="data.show">
<li ng-repeat="data in data.nodes" class="parent_li" ng-include="'tree_item_renderer'" tree-node></li>
</ul>
</script>
<ul>
<li ng-repeat="data in displayTree" ng-include="'tree_item_renderer'"></li>
Making a generic directive instead of ng-include is a cleaner solution:
Angular passing scope to ng-include
I am using ng-include with ng-repeat of an array containing string. If you want to send multple data so please see Junus Ergin answer.
See my code Snippet:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="">
<div ng-repeat="name in ['Sanjib Pradhan']" ng-include="'your_template.html'"></div>
<div ng-repeat="name in ['Chinmay Sahu']" ng-include="'your_template.html'"></div>
<script type="text/ng-template" id="your_template.html">
{{name}}
</script>
</div>