AngularJS: Directive with arbitrary start and end symbols - angularjs

What?
I'd like to use an Angular .directive by using arbitrary start and end symbols, e.g. square brackets:
<myDirective>callDirectiveAsUsual</myDirective><!-- usual directive call -->
<div>[[callDirectiveWithArbitrarySymbols]]</div><!-- new directive call -->
Why?
To make using a translation library much easier. Instead of annotating HTML, I would like to write [[TranslateMePlease!]].
Questions
Is it possible to define custom start and end symbols for a .directive? (According to the docs, this is not possible.)
Do I have to add a custom $interpolateProvider to the interpolation pipeline? (Assuming there is such an an interpolation pipeline in Angular.)
Do I have to write my own version of ng-bind? ng-bind-custom which uses its own $interpolateProviderCustom, which looks out for square brackets?

Related

Is it possible to access constants without injection?

I am using gulp-ng-config in my project to dynamically generate some constants at build time.
This is working just fine, but it got me and a colleague thinking about how constants are accessed in an angular app.
If you want to access constants in controllers that are defined on the same module that the constants belong to, do you still have to inject the constants by name to the controllers so you can access their values?
Looking at various examples, I'm pretty sure this is the only way - just wondered if there was some other way that didn't require a further dependency to be injected.
The constants injection is part of a best-practice-approach.
It's just a syntactical overhead preventing you from doing bad stuff like defining global variables and using them all over the place.
Of course you still can go ahead and define variables on the global window-scope and use them everywhere, but i cleary wouldn't suggest to do so.
So you can do
window.foo = 123;
and somewhere else
alert (window.foo);
this will show the wanted value but, of course, this is very bad practice.
You can also define variables on the angular $rootScope and use them anywhere. Yet, bottom line this is nothing else than defining them on window scope and shouldn't be done as well.
The last option (and probably the best for your scenario) is to define one constant OBJECT containing some more values. This way you just have to inject one constant object instead of many different ones.
Say you have two constants so far
$width = 1024
$height = 768
there is nothing bad about defining one injectable constant
$config = {
width: 1024,
height: 768
};
if you just want to access the $constant from outside the angular world you can always do it like this:
angular.element('body').injector().get('$constant')
assuming you declared your ng-app on the 'body' element or even further outside (like the 'html' element).
This is what dependency injection is made for : to force you to show all dependencies to your model.
Otherwise you can use the injector and use the method $get to get the values but i don't recommend it.
A last way would be to use a provider to store all constants and inject only the resulting service. However this will mask from which module each constants come from.

How to avoid leading whitespace being trimmed off of directive string bindings?

I'm creating a custom directive that I want to use to display the value of a field and an optional suffix (expected for units and such). Note that my example is shortened to stay concise.
My template looks something like
<div class="my-value">{{boundValue}}{{boundSuffix}}</div>
For the value, I'm using a two-way binding (=) and for the suffix, I'm using a string binding (&).
It worked great when I bound &deg into the suffix to display a temperature, but when I tried to bind in meters (note, there's a leading space - I don't want it pushed up against the number) the leading space seems to get trimmed and my result ends up looking like 123meters.
Using the chrome developer tools, I added a link function and inspected the directive's scope. By the time it reaches the link function, boundSuffix has already been trimmed. It seems like Angular is pulling some shenanigans on my behind the hood. Is there any way for me to avoid this trimming?
It's better to use angular filters to solve your problem. Filters allow to format your output as currency or as UPPERCASE (for example). Try to look here for more info. And here is working example

How to print 1 to 10 using ng-options without any js code?

I don't want to use any Javascript code or $scope variable.
Just want to print 1,2,3,4,5 values in Drop Down using ng-options.
This is what I have tried:
<select ng-name="priority" ng-options="priority for priority in Range(1, 5)"></select>
Working solution, within your requirements:
<select ng-model="priority" ng-options="priority for priority in [1,2,3,4,5]"></select>
Just in case, here's the plnkr to experiment with. If you have a quick look at the angular source code, you will see that ng-options requires select element as well as ng-model. Not sure what is the Range implementation mentioned in your example, but here is a very creative thread on this topic. Though, if your array is always the same and you really don't want to use scope (but why?), you're better off with the solution above.

Is there a way to add operators to AngularJS expression?

I would like to add beginsWith (^=) and endsWith ($=).
E.g., scope.$eval('"abcd" ^= "a"') should return 'true'
According to Angular's documentation on expressions, you should use controller\filter:
No function declarations or RegExp creation with literal notation
You can't declare functions or create regular expressions from within
AngularJS expressions. This is to avoid complex model transformation
logic inside templates. Such logic is better placed in a controller or
in a dedicated filter where it can be tested properly.

Wrapping Ruby With An Anonymous Module

There are several Ruby C API functions for running some Ruby code. Most just run the code in an isolated binding like require does. But some of them first wrap the code in an anonymous module before running it. For example, rb_load takes an argument for whether you want this wrapping, rb_eval_string_wrap is just rb_eval_string_protect but with wrapping.
In C, the wrapping looks like this:
/* load in anonymous module as toplevel */
th->top_self = rb_obj_clone(rb_vm_top_self());
th->top_wrapper = rb_module_new();
rb_extend_object(th->top_self, th->top_wrapper);
What is the point of doing this? I've tested these functions alongside their unwrapped equivalents and the result is always the same. Is there some use-case I'm not seeing?
I should've done some more testing. It looks like this is a bug.
The point of wrapping code in an anonymous module is to not pollute the toplevel namespace with constants/methods defined in the code. rb_load does this wrapping properly, rb_eval_string_wrap does not.

Resources