I have a problem with ng-repeat and ng-init. It doens'nt show me the content nor the ID when i ask for them in my code (project.content). But it doesn't show the text itself either. So somewhere something is going wrong. Note that I use other open and close tags for angular as default.
Appareantly Angular sees something different in the code as the browser or I do, as I recieve this console error:
http://errors.angularjs.org/1.2.12/$parse/ueoe?p0=projects%20%3D%20%7B
<table ng-init="projects = {" id":"1","content":"testtesttest"}="" "="">
How can I get this to work?
HTML code:
<div ng-app="overviewApp">
<table ng-init="projects = <?=json_encode($projects)?> ">
<tr ng-repeat="project in projects">
<td>[{[project.content]}]</td>
</tr>
</table>
</div>
Looks like this when in browser source code:
<!-- BEGIN PAGE CONTENT-->
<div class="row">
<div class="col-md-12">
<div class="content-section">
<div ng-app="overviewApp">
<table ng-init="projects = {"id":1,"content":"TestTestTest"} ">
<tr ng-repeat="project in projects">
<td>[{[project.content]}]</td>
</tr>
</table>
</div>
It cannot parse it because it is seeing double quotes inside double quotes. Try using single quotes.
<table ng-init='projects = <?=json_encode($projects)?> '>
Also you must ensure that projects is in array format like so:
ng-init='projects = [{"id":1,"content":"TestTestTest"}]'
Finally, since you are using a custom interpolate providers {[{ and }]}, you must define that in your config:
app.config(['$interpolateProvider', function ($interpolateProvider) {
$interpolateProvider.startSymbol('[{[');
$interpolateProvider.endSymbol(']}]');
}]);
See it working: DEMO
Alternatively, instead of using interpolation markup, I would recommend using the ng-bind directive like so:
<td><span ng-bind="project.content"></span></td>
See a DEMO.
NOTE: The AngularJS documentation recommends using a controller over the ng-init directive to initialize values on a scope.
Related
I have an array of messages
$scope.messsages = []
Upon clicking a button the content of a text area gets added into the array using ng-click method.This message is used to query the api. After which we get a response from the server which too is added into the array $scope.messages. All these messages are shown in html using ng-repeat i.e:-
<div ng-repeat="msg in messages track by $index">
{{ msg }}
</div>
However if I get a response from the server as a hyperlink string like
To know more click here.
The message that gets displayed in ng-repeat is a plain string with no hyperlinks. It renders the <a href="URL"> part as a string itself. I would like to represent it in html format.
One way it worked was by using
document.getElementById("demo").innerHTML = $scope.messages;
But I would like to know is there any angular way to do so in the ng-repeat part itself.
Thanks in advance
Include ngSanitize module on your app and then change your view as below
<div ng-repeat="msg in messages track by $index">
<div ng-bind-html="msg"></div>
</div>
Try to use like this
<div ng-repeat="msg in messages track by $index">
<div ng-bind-html="msg"></div>
</div>
Here is the plunk example for it.
You should use ng-bind-html for this. so you should inject ngSanitize in your app.
$scope.html = 'test';
$scope.trustedHtml = $sce.trustAsHtml($scope.html);
angular.module('myapp', ['ngSanitize'])
.controller('main', function($scope,$sce) {
$scope.messages = [{"link":"<a href='#/abc'>abc</a>"}];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-sanitize.min.js"></script>
<div ng-app="myapp" ng-controller="main">
<div ng-repeat="msg in messages">
<div ng-bind-html="msg.link"></div>
</div>
</div>
I've built a report which uses a set of nested ng-repeat directives to create what can be an enormous table. It works well to build the table, but after that, the scrolling performance is affected greatly - I assume this is due to what must be the large number of watches created by the ng-repeats.
The report only has to be built once and then is static. I don't need to watch the data continually.
I have two questions:
A) is there anyway to see a list of all the variables Angular is currently watching?
EDIT: This post was a great help in learning how to benchmark
B) Is there anyway to tell Angular to stop all of the watches it is doing? I've seen lots of posts about canceling watches which one sets up oneself, but that these are native directives, I'm not sure how I'd tap into them.
My preference would be to have a variable that I can say "if truthy, then do all watches, if not, then do not watch" or a function to just say "start watches" and "stop watches".
I have set up a very nice DOM watching service which can tell when all of the ng-repeats have executed, so I can know when I want to stop watching.
This is the table itself. Aside from tk-ng-repeat-completed, the other "tk-" attributes are just used for data and aren't actually directives.
<div class="table-responsive">
<table tk-sticky-column id="records" class="table table-striped table-hover table-condensed">
<!-- tbody[n] -->
<tbody class="dataset" ng-repeat="dataset in report.data track by $index" tk-ng-repeat-completed>
<!-- row[0] -->
<tr class="headline">
<!-- header[0] label -->
<th class="headline" style="background-color:#042E34;">
<div style="width:200px;"><h4>{{report.labels.y[$index]}}</h4></div>
</th>
<!-- header[n] label -->
<th ng-repeat="x_label in report.labels.x" tk-ng-repeat-completed
class="datapoint date"
tk-raw-data="{{x_label}}">
<em><small>{{x_label}}</small></em></th>
<!-- header[last] space for addition #todo remove this, add during calculations -->
<th class="date"></th>
</tr>
<!-- row[n] -->
<tr ng-repeat="(key, datapoints) in dataset" tk-metric-key="{{key}}">
<!-- column[0] label -->
<td tk-metric-key="{{key}}"
tk-calc="{{report.labels.data[key].calc}}"
class="rowdesc begin">{{key}}</td>
<!-- column[n] data -->
<td ng-repeat="datapoint in datapoints track by $index" tk-ng-repeat-completed
ypos="{{$parent.$parent.$parent.$index}}" xpos="{{$index}}" tk-metric-key="{{key}}"
class="datapoint"
tk-raw-data="{{datapoint}}">
{{datapoint}}</td>
</tr>
</tbody>
</table>
</div>
I'd recommend checking out the single-bind syntax they introduced in 1.3, if you're on a version greater than or equal to that one. It works really well and is very simple to implement. Here's an example:
normal syntax, which creates a watcher for each variable:
<div ng-repeat="foo in vm.bar">
{{foo}}
</div>
single-bind syntax, with no watcher on the nested variable inside the repeat:
<div ng-repeat="foo in vm.bar">
{{::foo}}
</div>
edit:
I forgot to mention that if your data isn't going to change at all after it gets populated the first time (e.g. from a $http.get), you can also just use the single-bind syntax on the top level ng-repeat:
<div ng-repeat="foo in ::vm.bar">
{{::foo}}
</div>
I want to catch the first iteration in ng-repeat directive:
<div ng-repeat="product in products">
<div is-open="{if "[[$index]]" == 0}true{else}false{/if}">
...
</div>
</div>
But it doesn't work. Setting 0 as string also doesn't work. Comparing in angular also doesn't work.
How can I do that?
Try:
<div is-open="{{$index == 0}}"></div>
You should use special property $first of ng-repeat with ternary operator. Like see below snippet
<div ng-repeat="product in products">
<div is-open="($first) ? true : false">
...
</div>
</div>
I suppose smarty code will not work as you're expecting. Smarty is a server side programming language and angular runs on client side. In your query, smarty tags are unnecessary being called in angular directive. Above trick will work for you.
There are also some couple of special properties available too. You can check them out here
I am trying to implement infinity type scrolling on a simple grid. Html is like this:
<div class="text-center" style="background-color:#eee;">
<H2 style="margin-top:0px;">Customer List</H2>
<hr />
Search: <input ng-model="customerVm.search" /> <br /> <br />
<table class="table table-hover" ui-scroll-viewport style="height:500px;">
<tbody>
<tr ui-scroll="customer in customerVm.datasource" ng-model="customerVm.gridResult" "buffer-size="10">
<td>
</tbody>
</table>
</div>
I want to filter what is in the grid based on the search box model, seems simple enough. I would normally just use the following with an ng-repeat
<tr ng-repeat="customer in customerVm.datasource | filter:customerVm.search" ng-model="customerVm.gridResult" "buffer-size="10">
<td>{{customer.customername}}</td>
</tr>
However with the use of "ui-scroll" instead of ng-repeat I am getting an error
Expected uiScroll in form of '_item_ in _datasource_' but got 'customer in customerVm.datasource | filter:customerVm.search'
Am I missing something on how to filter the data using Angular-ui scroll? I see the line in the scroll lib that is causing the issue which throws an error if there is anything other then
item in datasource
This makes me think that filtering is not possible in Angular-ui scroll. Any ideas folks?
Filtering is unfortunately not yet possible in this way, as the error suggests. See "Parameters" in the Readme file. You could implement your own filter in the data source "get" function. See also the official examples.
I have the following code:
<div ng-repeat="item in items">
<div ng-include src="itemG.html"></div>
</div>
then in itemG.html I have:
<img src="{{item.image}}">
How can I get my ng-repeat to print out all of the images?
There are 2 potential problems in the code...
src="itemG.html" needs an extra pair of single quotes like this:
<div ng-repeat="item in items">
<div ng-include="'itemG.html'"></div>
</div>
And the img tag is missing a closing ":
<img ng-src="{{item.image}}">
Plunker: http://plnkr.co/edit/7IUs7WPdUYkfVVKtBN1m?p=preview
Basically, what this comes down to is that the browser will interpret what inside the src attribute literally, until angular comes along to replace it. If you have a string constant, you can use single quotes inside the src="'myurl.html'", but if you have a value that needs to be bound by angular, you have to use ng-src and the expression syntax of {{ }}
You also need to bind a model to your template file itself. It's not going to pick up the bindings from your repeater without some help from either the ng-include event directives, or it's own model/controller/directive. There are too many different ways to demonstrate that, and it's also relevant on what markup is in your template file, which I can't say.
However, if the img tag is the only thing in that file, then instead of the file, I'd just do this:
<div ng-repeat="item in items">
<img ng-src="item.image" />
</div>
Since you're inside a repeat, it's already being included, making the ng-include redundant.
In principal code
<div ng-repeat="item in items">
<ng-include src="itemG.html" ng-controller="MyCtrl" ng-init="i=item"><ng-include>
</div>
then in itemG.html I have:
<img src="{{i.image}}">