ng-repeat angularjs 1.5.11 not work - javascript

i have an angularJS v1.5.11 app,
but i've got big problem when i want to do a simple ng-repeat in table like
<tbody>
<tr ng-repeat="score in data.result">
<td ng-repeat="item in score"> {{ item }} </td>
</tr>
</tbody>
my code works fine on angularJS v1.1.1,
hope you can help me.
i made a JSFiddle here : https://jsfiddle.net/vpLj20w1/5/
u can change AngularJS framework version in JSFiddle to see work fine on 1.1.1, but on 1.4.8 and higher doesn't work..
best regards,
Axel.

You need to tell angularjs that your controller exists. Try declaring a module and adding the controller to the module:
<div ng-app="myApp">
<div ng-controller="scoreCtrl">
...
</div>
</div>
and then add to your javascript:
var app = angular.module("myApp", []);
app.controller("scoreCtrl", scoreCtrl);
Now it runs better than it did, but you have a problem with ng-repeat="item in score" as angularjs needs a unique key for anything used in ng-repeat and you have duplicated items.
Change the inner loop to:
<td ng-repeat="item in score track by $index"> {{ item }} </td>
and now you should get the expected output.
BTW, looking at the javascript console in your browser would have helped you here: initially it was complaining that it couldn't find the controller function and then when I injected it into the app it complained about the repeater.

This is because you haven't injected your controller into the app. I can't explain why your example works on 1.1.1, as I only have experience on 1.4.x+, but you need to use the module controller injection.
https://jsfiddle.net/vpLj20w1/7/
angular.module('app', [])
.controller('scoreCtrl', scoreCtrl);
And give your ng-app a name (I used app)

Related

Unable to make NgTable work with AngularJs 1.5

I'm trying to integrate NgTable with angularjs 1.5 in a component-based architecture (so, no old-style controllers).
The NgTable controls (filter, icons for sorting) appear, but they don't seem to work at all, so they don't filter and don't sort.
Here's my code
--- activity-list-module.js ---
angular.module('activityList', ['ngTable']);
--- activity-list-component.js ---
(function(){
'use strict';
angular.
module('activityList').
component('activityList', {
templateUrl: "app/activity-list/activity-list.html",
controller: ['NgTableParams', function (NgTableParams) {
var self=this;
self.activitiesForm=[{id:0,description:"att0"},{id:1,description:"att1"},{id:2,description:"att2"}];
self.tableParams = new NgTableParams({}, { dataset: self.activitiesForm});
}]
});
})();
--- activity.list.html ----
<div style="margin:20pt">
<h3>Manage Activities</h3>
<div style="margin:20pt">
<h3>Manage Activities</h3>
<div class="row" style="margin-left:20pt" >
<table id="myViewTable" ng-table="$ctrl.tableParams" class="table" show-filter="true" class="table actTable" style="width:95%;table-layout: fixed;" >
<tbody>
<tr ng-repeat="projectActivity in $ctrl.activitiesForm track by projectActivity.id">
<td data-title="'Id'">{{projectActivity.id}}</td>
<td data-title="'description'" filter="{ description: 'text'}" sortable="'description'">{{projectActivity.description}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Of course the component is called using the tag <activity-list></activity-list> in another page.
I'm working with AngularJs 1.5.8 and ng-table 3.0.1.
I'm doing something wrong or there is an incompatibility between AngularJs >= 1.5 and ng-table ?
Here is the plnkr
PS In the last case, how can I do ? Is smarttable compatible with AngularJs 1.5 ?
After raised an issue in ng-table GIT repo i got a working example from the creator of ng-table and i could have a look.
The point is in the use of controller variables, instead of a $data variable generated by ng-table.
So, in the case of the 'new style' component the issue is solved changing
<tr ng-repeat="projectActivity in $ctrl.activitiesForm track by projectActivity.id">
with
<tr ng-repeat="projectActivity in $data track by projectActivity.id">
In the case of the "old Style" controller it's solved changing
<tr ng-repeat="user in vm.data">
with
<tr ng-repeat="user in $data">
I don't like a lot this solution, because it add a kind of global, but it works.
EDIT
it works also using
$ctrl.tableParams.data (for Component Example) and vm.tableParams.data (for the Controller Example) which let me feel much better about.

How can I use *ngFor current object outside of the ngFor?

The title might seem weird but what im talking about is basically what this link is doing.
Im look for a way to use the current iterated person in a <tr> outside of the *ngFor scope.
In the link he used ng-repeat-start and ng-repeat-end to include multiple tag withing the ng-repeat. How can i achieve the same behavior withing Angular2 using *ngFor?
I had to use the <template> tag, which made the iterated objected accessible within it.
<ng-template let-person ngFor [ngForOf]="people">
<tr>
<td>{{person.name}}</td>
<td>{{person.gender}}</td>
</tr>
<div>
<span>{{person.details}}</span>
</div>
</ng-template>
Hope it'll help somebody
The * in *ngFor (and really any angular directive) is shorthand that tells angular to surround the element in an ng-template, which is just the angular implementation of . You can read about how that happens at https://angular.io/guide/structural-directives, but I'll reproduce the relevant example below.
If your code contains
<div *ngIf='object'>{{object.property}}</div>
as part of the render process, angular transposes that to
<ng-template [ngIf]='object'>
<div>{{object.property}}</div>
</ng-template>

angular and isotope - Adding new item within isotope context

UPDATE: After some very insightful code from #Marc Kline, I went back and cleaned up my page. It turned out that I had my controllers listed in reversed (My angular controller was inside the Isotope controller, instead of the other way round). Once I changed it back and cleaned off some additional scripting, it started working again. I have updated the code snippet to reflect the change. Thanks to Marc and S.O!
I am having trouble figuring out how can I add new items using Angular and still let Isotope manage their UI display.
I am using Isotope and Angular to render server results in a masonry style layout. When I add new items to the layout on a button click, angular adds it just fine. However, they do not appear in the context of the isotope UI and appear separately (and cannot be sorted, laid out or filtered using Isotope).
Here is my JS Code
<!-- Define controller -->
var contrl = app.controller("MainController", function($scope){
$scope.items ={!lstXYZ}; //JSON data from server
//Function called by button click
$scope.addItem = function(item)
{
$scope.items.push(item);
$scope.item = {};
}
});
contrl.$inject = ['$scope'];
Here is the HTML to display the server results...(Updated to show working code..refer comments)
<div ng-controller="MainController">
<div class="isotope" id="isotopeContainer">
<div ng-repeat="item in items">
<div class='element-item {{item.status}}' data-category='{{item.status}}'>
<p class="number">{{item.type}}</p>
</div>
</div>
</div>
</div>
And here is my HTML button to add the new items
<table>
<tr>
<td><input type="text" ng-model="item.status" /></td>
</tr>
<tr>
<td><input type="text" ng-model="item.type" /></td>
</tr>
<tr>
<td colspan="2"><input type="Button" value="Add" ng-click="addItem(item)" /> </td>
</tr>
</table>
I am not sure how do I ensure that Isotope can recognize the newly added element and re-animate the layout.
Any help or pointers will be very appreciated. Thanks!
ng-repeat takes care of adding the new element to the DOM for you. However, Isotope isn't doing any "watching" for you - you have to manually invoke a redraw of the container.
You could just add something like $("#isotopeContainer").isotope(...) directly to your controller, but in the spirit of keeping your controllers lean and free of DOM-related code, you should instead create a service. Something like:
myApp.service('Isotope', function(){
this.init = function(container) {
$(container).isotope({itemSelector: '.element-item'});
};
this.append = function(container, elem) {
$(container).isotope('appended', elem);
}
});
... where the first method initializes a new Isotope container and the next redraws the container after an item is appended.
You could then inject this service into any controller or directive, but directives probably are best for this scenario. In this Plunker, I created two new directives: one for Isotope containers and another for Isotype elements, and used the service to do the initialization and redrawing.
In this particular case, my code was not written correctly. I have updated the question's code but wanted to mention it more clearly here...
Apparently, the beauty of Angular is that you do not need to bother with the underlying UI framework (Isotope in this case). As long as you update the Angular data array, the UI binding is updated automatically.
The only gotcha is to ensure that the UI framework div is within the context of your Angular div.
Here is the non-working code...Note that the isotope div is outside the Angular controller.
<div class="isotope" id="isotopeContainer">
<div ng-controller="MainController">
<div ng-repeat="item in items">
<div class='element-item {{item.status}}' data-category='{{item.status}}'>
<p class="number">{{item.type}}</p>
</div>
</div>
</div>
</div>
Here is the updated code with isotope running within the Angular controller context...
<div ng-controller="MainController">
<div class="isotope" id="isotopeContainer">
<div ng-repeat="item in items">
<div class='element-item {{item.status}}' data-category='{{item.status}}'>
<p class="number">{{item.type}}</p>
</div>
</div>
</div>
</div>
Hope this helps. I am thankful for all the responses and help I got from SO. Appreciate the learning opportunity.

AngularJS - Difference between creating controllers

I am new to AngularJS. When i am creating a controller, I have seen two examples which show how to do it differently. How ever the one that most show is the way to do it doesnt work.
The issue with the first one, is that it either can't find the module, or it cant find the function. And it ends up just as {{type}} {{name}}. How ever if i try on plnkr then the first one works.
'dataControl' is not a function, got undefined
Is the error i am getting
If i have my html as this.
<html ng-app>
<head>
</head>
<body ng-app="docsBindExample">
<script src="../bower_components/angular/angular.min.js"> </script>
<script src="../scripts/controllers/main.js"></script>
<div ng-controller="dataControl">
<select id="selected" ng-model="type">
<option>Total Revenue</option>
<option>Total Expenditure</option>
<option>Total Number of Events</option>
<option>Amount of Mail</option>
<option>Average Delivery Times</option>
<option>Critical Routes</option>
</select>
{{type}}
{{data}}
<ul>
<li ng-repeat="values in data">
{{values.dataName}}
{{values.dataValue}}
</li>
</ul>
</div>
</body>
</html>
And then the first controller, that doesnt work.
angular.module('docsBindExample', [])
.controller('dataControl', ['$scope', function($scope) {
$scope.name = 'Value Is here';
}]);
Secondly, the other controller that does work
function dataControl ($scope) {
$scope.name = 'Value Is here';
}
Is there any draw back from using the second ?
There is no any such drawback using the second approach. However the first approach is quite convenient one for the big applications as you will be defining your modules and registering controllers, filters etc against your modules. The reason behind your first approach is not working is may be you have not defined docsBindExample module. Trying doing this:
var docsBindExample = angular.module('docsBindExample', []);
and then your controller definition.
Try using the following
Working Demo
html
<div ng-app="docsBindExample">
<div ng-controller="dataControl">
<select id="selected" ng-model="type">
<option>Total Revenue</option>
<option>Total Expenditure</option>
<option>Total Number of Events</option>
<option>Amount of Mail</option>
<option>Average Delivery Times</option>
<option>Critical Routes</option>
</select>
{{type}}
{{data}}
<ul>
<li ng-repeat="values in data">
{{values.dataName}}
{{values.dataValue}}
</li>
</ul>
</div>
</div>
script
var app = angular.module('docsBindExample', []);
app.controller('dataControl', function ($scope) {
$scope.name = 'Value Is here';
});
Syntactically both works perfect but the first approach is recommended than the second one. In first approach the controller will be attached to that module and is been a good practice for building an application.
For more details visit this link
https://docs.angularjs.org/guide/controller
And there is no error when I executed your code.
Your code is working for me!!!!
Check: http://plnkr.co/edit/hrkSDOinTcMEmPLcttut
Maybe this links from Stackoveflow works for you!!!
AngularJS - different ways to create controllers and services, why?
Globally defined AngularJS controllers and encapsulation
The first is definitely the recommended way (if nothing else because it does to polute the global object).
I haven't tried it myself, but I am pretty sure you are going to run into trouble when your application becomes more complex (with more than 1 modules and/or external dependencies).
The error you get is probably due to some JS error (e.g. a syntax error) which csuses the dataControl to fail registering as a controller.
Unfortunately, such errors are annoyingly undescriptive and hard to track down.
I suggest commenting out all the code inside the controller definition and then uncomment block by nlock until you find the problematic line.
For me, more than a few times, such errors where caused by a wrong object declaration:
E.g. {prop = val} instead of {prop: val} or {p1:v1; p2:v2} instead of {p1:v1, p2:v2}
try changing it to:
.controller('dataControl', function($scope) {
//more code
});

Sort or Rearrange Rows of a table in angularjs (drag and drop)

I wanted to have the functionality of rearranging rows in a table (sorting rows using drag and drop).
And the index of the row arrangement should also change in the model.
How can I do something similar to this : http://jsfiddle.net/tzYbU/1162/
using Angular Directive?
I am generating table as :
<table id="sort" class="table table-striped table-bordered">
<thead>
<tr>
<th class="header-color-green"></th>
<th ng-repeat="titles in Rules.Titles">{{titles.title}}</th>
</tr>
</thead>
<tbody ng-repeat="rule in Rules.data">
<tr>
<td class="center"><span>{{rule.ruleSeq}}</span></td>
<td ng-repeat="data in rule.ruleData">{{statusArr[data.value]}}</td>
</tr>
</tbody>
</table>
I did it. See my code below.
HTML
<div ng:controller="controller">
<table style="width:auto;" class="table table-bordered">
<thead>
<tr>
<th>Index</th>
<th>Count</th>
</tr>
</thead>
<tbody ui:sortable ng:model="list">
<tr ng:repeat="item in list" class="item" style="cursor: move;">
<td>{{$index}}</td>
<td>{{item}}</td>
</tr>
</tbody>{{list}}
<hr>
</div>
Directive (JS)
var myapp = angular.module('myapp', ['ui']);
myapp.controller('controller', function ($scope) {
$scope.list = ["one", "two", "thre", "four", "five", "six"];
});
angular.bootstrap(document, ['myapp']);
There is another library: RubaXa/Sortable: https://github.com/RubaXa/Sortable
It is for modern browsers and without jQuery dependency. Included is a angular directive. I'm going to check it out now.
You get good touch support additionally.
AngularJS was not really built for the manipulation of DOM elements, rather to extend the HTML of a page.
See this question and this Wikipedia entry.
For DOM manipulation, jQuery/mootools/etc will suite you just fine (hint: the example in your jsFiddle link).
You could probably use AngularJS to keep track of the ordering of your elements to update your model. I'm not sure how to do this using directives, but the following code may be useful
var MyController = function($scope, $http) {
$scope.rules = [...];
...
}
var updateRules = function(rule, position) {
//We need the scope
var scope = angular.element($(/*controller_element*/)).scope(); //controller_element would be the element with ng-controller='MyController'
//Update scope.rules
}
Then when you reorder the list, simply call updateRules() with the changed rule and its new position in the model.
Anyone else who wants something like this but not understanding the accepted answer. Here is a directive UI.Sortable for AngularJS that allows you to sort an array/ table rows with drag & drop.
Requirements
JQuery v3.1+ (for jQuery v1.x & v2.x use v0.14.x versions)
JQueryUI v1.12+
AngularJS v1.2+
Usage
Load the script file: sortable.js in your application: (you can find this sortable.js from here
<script type="text/javascript" src="modules/directives/sortable/src/sortable.js"></script>
make sure you have included JQuery, AngularJs and JQueryUI js files in
order before this sortable file
Add the sortable module as a dependency to your application module:
var myAppModule = angular.module('MyApp', ['ui.sortable'])
Apply the directive to your form elements:
<ul ui-sortable ng-model="items">
<li ng-repeat="item in items">{{ item }}</li>
</ul>
Developing Notes:
ng-model is required, so that the directive knows which model to update.
ui-sortable element should contain only one ng-repeat
Filters that manipulate the model (like filter, orderBy, limitTo,...) should be applied in the controller instead of the ng-repeat
3rd point is very Important as it took almost an hour to understand
why my sorting was not working?? It was because of orderBy in html
and that was resetting the sorting again.
For more understanding you can check the detail here.
If I understand you correctly, you want to be able to sort the rows? If so, use UI-Sortable: GitHub
Demo: codepen.io/thgreasi/pen/jlkhr
Along with RubaXa/Sortable there is one more angularjs library avilable that is angular-ui-tree. Along with drag and drop we can arrange elements in a tree structure and we can add and delete elements (nodes)
Please see the this link for examples
http://angular-ui-tree.github.io/angular-ui-tree/#/basic-example .
Please see this for github
https://github.com/angular-ui-tree/angular-ui-tree.

Categories

Resources