using javascript inline in angularjs - javascript

I have an array in my controller containing date-objects called $scope.events. I would like to iterate these events and and print them out in a certain format, which I use momentjs for.
Now the thing is, I cannot get it to actually use momentjs.
I have tried the following:
<table>
<tr ng-repeat="ev in events">
<td>{{ moment(ev).format("HH") }}</td>
</tr>
</table>
but this just prints an empty cell.
So my question is, how do I use javascript, momentjs, inline in my angular-binding ?
thanks
Thomas

Assuming moment is a property of window, you'll need to create a reference in this object's $scope that references moment.
Very simply:
$scope.moment = window.moment;
Here's a plunkr showing internal $scope methods vs. a $scope property referencing a method on window:
http://embed.plnkr.co/PWFK80/preview
That's the simple answer, but you'd likely want to wrap this library into its own directive or service, so that you could use it without coupling higher-level objects to the window object unnecessarily.

Wrap the code in a function in your controller for a quick answer.
controller('Ctrl', function($scope) {
$scope.moment = moment;
});
I edited this to match a comment by #Stewie because it looks better
and in your html:
<td>{{moment(ev, 'HH'}}</td>
Or make a service/directive for moment for something better.

Related

How to use ng-translate with variables resolved from controller?

I'm using ng-tranlate for i18n.
I'd like to combine a translated label together with a variable resolved from controller binding. How can I achieve the following?
<div translate="my.lang.text">some more: {{controller.attribute}}</div>
This does not work, and ng-translate ignores any content between the divs. why?
The translate directive will replace the content of the element with the translation you pass to it.
The use case you are describing looks like a parameterized translation. If you want to keep the use of the directive, you could pass the variable through the translate-values directive:
<div translate="my.lang.text"
translate-values="{value: 'some more: ' + controller.attribute}"></div>
You have to specify that your translation is parameterized:
JSON
"my.lang.text": "This is a parameterized string {value}"
I believe the translate directive replaces all the element's content with the translation.
In this case, you probably want to use the translate filter instead.
<div>{{'my.lang.text' | translate}} some more: {{controller.attribute}}</div>
As an alternative, you could also avoid this issue by giving the translated value it's own element.
<div><span translate="my.lang.text"></span> some more: {{controller.attribute}}</div>
If the translation is always intended to have have a value appended to it, then using a parameterized translation is probably the best solution (as suggested by Michael https://stackoverflow.com/a/33419608/90305)

Why do the Angular docs recommend against ng-init in most cases?

From the ng-init documentation:
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
That doc goes on to give the following example:
<div ng-repeat="innerList in list" ng-init="outerIndex = $index">
// [snip]
</div>
What makes it appropriate to use ng-init with ng-repeat but not, for example, with ng-model like this:
<input ng-model="thing.prop"
ng-init="thing.prop = thing.prop || 'defaultValue'">
The doc says one should "use controllers rather than ngInit". What benefit does a controller offer in this case? Is this an Angular stylistic preference, or are there cases in which code like the above will not work?
That's because the documentation should be as concise as posible, and if in each example they create a Controller, it won't be so precise and clear

Other ways to bind HTML to JavaScript

I know two ways to bind HTML to client-side JavaScript code and stay a kind of object-oriented:
Use a lot of IDs (or special CSS class names, or some other distinct HTML attributes) in HTML and do a "harvest" in JS initialization method (or request each DOM object each time, right before use);
Do not write HTML at all. Construct an element at runtime, in initializer, and remember a reference to DOM object (or jQuery object) in a variable.
Are there some other ways that allow to use design-time phase (writhing HTML) which is much more convenient than doing all the work at runtime, and at the same time do not use a lot of identifiers of any kind having to maintain their uniqueness?
AngularJS is the framework you want to use for 2-way data binding.
I used AngularJS for multiple projects now, combined with nodeJS, and I never looked back at jQuery, you keep your code clean with the MVC pattern and manipulating the DOM is made easy and clear.
Example for 2 way data binding:
HTML
<p>{{elementText}}</p>
<input type="text" ng-model="item.value" />
JavaScript/Controller
$scope.item = {
value: ''
};
$scope.elementText = "The text you want to display";
console.log($scope.item.value); //Directly get your values from the scope.
Want to assign values to <select> boxes or fill <table>'s using JSON data? No problem, AngularJS got you covered.
Interesting AngularJS features:
ng-model
ng-repeat
Animations
Custom directives
I hope this will help you!

Variables variables possible in angularjs?

Im working in a basic translation service for angularjs, I have an object in the view with the translations this way:
var translations = {"name":"Name", "address":"Address", "phone":"Telephone"};
So I want to replace if I found the {{phone}} in the view with the value of its translation: "Telephone".
Is there some way to call variables variables while iterate, like this:
<div class="item item-text-wrap" ng-repeat="(k, v) in profile_fields">
<b>{{translations. {{k}} }}</b>
</div>
Thanks in advance!
Sure, just use this:
<b>{{translations[k]}}</b>
Basically, access the translations object like you would in JavaScript, using the k variable.
Keep in mind that you never have to nest those brackets ({{}}) deeper than this.
Also, Angular Translate is a pretty nice translations library. You might want to have a look at it.

How do I get the current child-scope of a ngRepeated element in AngularJS?

This seems like a simple question, but I've been googling around for a while and can't seem to find it.
In my JS I have something called parseTags(book) that takes a JSON comma-separated list of tags (book.tags) and parses it into an array:
$scope.parseTags = function(book){
book.tags = book.tags.split(',');
};
In my HTML I have something like this:
<div ng-repeat="book in books" ng-init="parseTags(book)">{{book.title}}</div>
Is there a way just to get the child scope from within the $scope.parseTags function? Instead of passing in book each time?
Something like:
$scope.parseTags = function($childScope){
$childScope.tags = $childScope.tags.split(',');
}
<div ng-repeat="book in books" ng-init="parseTags()">{{book.title}}</div>
parseTags function is executed in context of the current child scope. So parseTags can also be written as:
$scope.parseTags = function() {
this.book.tags = this.book.tags.split(',');
};
Demo: http://plnkr.co/edit/DUkDVOMjjj0khh5KCYo7?p=preview
you should only use ng-init for special cases when you need to use a property of the ng-repeat, I think you will better doing this kind of functionality in the controller. Unless there is a really specific reason you can't do that. I haven't seen your use of tags in the html, but looks like the kind of functionality a filter would do.
From angularjs docs:
The only appropriate use of ngInit is for aliasing special properties
of ngRepeat, as seen in the demo below. Besides this case, you should
use controllers rather than ngInit to initialize values on a scope.
source: angularjs docs

Categories

Resources