Let's say you have a list of items that are rendered 3x per row, like:
<div ng-repeat="piece in fooService.get()" class="span3">
And you want to be able to sort them. The only way I have found is to wrap with:
<div ui-sortable>
Which works, but does not bind to the model.
What am I missing?
You have to pass the ng-model as well:
See the below fiddle i found googling:
http://jsfiddle.net/g/hKYWr/
Edit
Reference:
http://plnkr.co/edit/Bzjruq?p=preview
Related
HTML:
{{vm.regions}}
<div ng-repeat="region in vm.regions">
{{region}}
</div>
On button presses, the model a.k.a vm.regions gets updated in the controller. For example vm.regions = [].
I can see that the array {{vm.regions}} is instantly updated, but the elements in the div take at least a second to update, meaning you can see old elements for a bit in the newly updated list, for example.
What is causing this?
It is in AngularJs Best Practices to always add "track by $index" in order to inprove performances.
{{vm.regions}}
<div ng-repeat="region in vm.regions track by $index">
{{region}}
</div>
Link : https://docs.angularjs.org/api/ng/directive/ngRepeat
Try using vs-repeat. It applies virtual scrolling to ng-repeat which increases its performance drastically even if you are not using one time binding.
http://kamilkp.github.io/angular-vs-repeat/#?tab=8
I use quick-ng-repeat Quick-ng-repeat for my list to iterate because it is a huge list and I would improve performance.
Now I recognized that if I change the model, the view is not updated with this code:
<span quick-ng-repeat="item in collection track by $index" quick-repeat-list="items">
{{ item }}
</span>
With this code
<span ng-repeat="item in collection track by $index">
{{ item }}
</span>
every works fine.
Does anyone have any idee why this happens?
Thanks a lot!
quick-ng-repeat does not implement deep watch just like ng-repeat, it implement one way binding approach. So if your model changes frequently, don't use it.
In Angular 1.2 a new addition was made to the syntax of ngRepeat: the amazingly awesome track by clause. It allows you to specify your own key for ngRepeat to identify objects by, instead of just generating unique IDs.
This means that you can change the above to be ng-repeat="task in tasks track by task.id" and since the ID would be the same in both your original tasks and the updated ones from the server – ngRepeat will know not to recreate the DOM elements and reuse them
The Quick ng-repeat is doing one way binding ,it something similar to what we do in angularjs
<div ng-repeat="item in ::items">{{item.name}}</div>
This does not create unnecessary watches.
I think Quick-ng-repeat use Single binding same as in angular 1.4 like (::).Single binding mean it will be create a watcher for your repeat that why it will not effect when object is change.
<div ng-repeat="obj in ::objList">{{obj.name}}</div>
I am running this simple code with angularjs :
HTML :
<div ng-app ng-controller="AController">
<code>{{ itemsInArray }}</code>
<div ng-repeat="item in itemsInArray">
<input ng-model="itemsInArray[$index]" />
</div>
</div>
JavaScript :
function AController($scope) {
$scope.itemsInArray = ["strA", "strB", "strC"];
}
Binding appears to be working correctly when indexing into the array but after entering one character the input loses focus.
You can find the working code here on this fiddle : http://jsfiddle.net/QygW8/
I think this is happening because you are manipulating the same item which is iterated over ng-repeat. So ng-repeat sees a change in the item and re-runs the `ng-repeat which regenerates the items.
If you look at your fiddle html, you may notice this effect.
To make it work, one way you can do this
http://jsfiddle.net/cmyworld/CvLBS/
where you change your array to object array
$scope.itemsInArray = [{data:"strA"}, {data:"strB"}, {data:"strC"}];
and then bind to item.data
Try to change the model:
<div ng-repeat="item in itemsInArray">
<input ng-model="item" />
</div>
Even am an newbie to the angularjs, up-to my findings ng-repeat updates/repeats and recreates the whole HTML elements when there is an change in the model. Hence when a single character added to model causes ng-repeat to react and creates the all the HTML elements again which results to losing the focus.
This is an fiddle , In which u will be able to observer the changes with the model inside the ng-repeat and outside the ng-repeat.
Sorry i don't have the solution, Hope using ng-change apart of ng-model may help.
I'm using Foundations with AngularJS. I have a case where I'm trying to display things in columns using ng-repeat.
<div class="four columns" ng-repeat="resultsObject in resultsObject">
<div ng-bind-html-unsafe="resultsObject"></div>
</div>
This works fine. But the issue is that the columns size could be anywhere from 1-5. And I'd like the display to update dynamically. So if there are only 2 columns, it would adjust to the correctly column display.
<div class="{{$rootScope.columnCount}} columns" ng-repeat="resultsObject in resultsObject">
<div ng-bind-html-unsafe="resultsObject"></div>
</div>
When I try doing something like the above code, {{$rootScope.columnCount}} doesn't display anything. (I have verified that it does accurately store the correct column based on input.) It shows up in the source as <div class=" columns"> instead of <div class="3 columns">.
Is this an issue with using an angular variable and ng-repeat in the attribute? I've used {{$index}} within the class - so I know it can print things out within the class attribute.
Without seeing some code, I would assume the number of columns is equal to resultsObject.length so can you try:
<div class="{{resultsObject.length}} columns" ...
Here is a short demo.. Check out the class of each li and you'll see the count.
http://plnkr.co/edit/fFRTjD5gse8tnJmDig2I?p=preview
Lastly can you just try to bind to class="{{columnCount}} columns">... I don't think you need to reference the $rootScope.
The problem was an issue with variables overlapping. Apparently I had used columncount in other places in my app. So it just kept getting set back to an null. Simply changing the name solved the problem.
Is there a way to have a HTML-view with pre-populated values from the server, and then get AngularJS to read those values into it's $scope?
I'm thinking of a scenario where the HTML is like this:
<div ng-controller="TestController">
<div ng-bind="title">Test Title</div>
<div ng-bind="itemCount">33</div>
<div ng-repeat="item in items">
<div ng-bind="item.title">Item 1 Title</div>
</div>
</div>
<button ng-click="update()">Update</button>
And the JavaScript is like this:
function TestController($scope) {
$scope.update = function() {
console.log($scope.title); // Should log "Test Title"
};
}
The thought behind this is to let the server render HTML that search engines can index, but have a JavaScript-model-representation of the content for manipulation through JS.
While ng-init is one solution, it requires you to explicitly set the value. So here is an alternative solution.
http://plnkr.co/edit/pq8yR9zVOHFI6IRU3Pvn?p=preview
Note : This solution wont work for ng-repeat. Control flow directives cant be used with this. But for simple extraction of information from ng-bind this works pretty well. All that you need to do is add the default directive ( code in plunk ) to wherever you are doing the bind and it will extract the text content and push it to the scope variable.
EDIT (solution with ng-repeat):
So, I was thinking of a way to make ng-repeat also work the same way. But getting ng-repeat to work like this isnt an easy job ( see the code for proof :P ). I have finally found a solution - here you go :
http://plnkr.co/edit/GEWhCNVMeNVaq9JA2Xm2?p=preview
There are a couple of things you need to know before you use this. This hasnt been thoroughly tested. It only works for repeating over arrays ( not objects ). There could be cases that have not been covered. I am overriding ngRepeat itself which could have other consequences. When you loop through the items ( in your server side code ) dont forget to add default="true" on the first element and default on the rest of the elements.
Hope this helps.
Add ng-init to your elements with the value so that it will work the way you want.
http://docs.angularjs.org/api/ng.directive:ngInit
I think what you really want is to make your application searchable by serving static files in parallell. Read more about it here http://www.yearofmoo.com/2012/11/angularjs-and-seo.html