What's the best way to write directives? - angularjs

I've been struggling with the way to implement a good structure for directives in TypeScript. I've found couple of solutions online, however to be honest, I have no idea which one to use - they all do their job.
What is a good structure for a directive to stick to?
n.b. I'm using AngularJS 1.

In my opininion, thinking on Typescript Way, you need to import the AngularJS definition, this gives you references on the framework.
Create a Module
Export a Function that returns a Angular Directive Definition Object
In ddo use the APIs as you wish
[...] export function tsDirective(): ng.IDirective [...]

Related

In which cases there is need to use of AngularJS factory with Typescript?

I have an app with AngularJS and TypeScript
I want to know is there any case when I should use AngularJS factory instead of TypeScript Static Class
Nothing changes with ES6/TypeScript classes. They are just syntactic sugar for JavaScript constructor functions.
Good use cases for factory services can be figured out by the process of elimination.
Since service services are preferable for OOP-flavoured units:
class FooClass {
static $inject = [...];
constructor(...) {}
}
app.service('foo', FooClass);
And value services are preferable for singleton units that aren't constructed from classes and don't involve DI:
app.value('bar', 'bar');
app.value('Baz', BazClass);
factory services can be used for the rest of the cases. I.e. when a service needs DI and returned value cannot be easily constructed from a class - a function, a primitive, an object that is returned from function call:
app.factory('qux', ($q) => $q.all([...]));
We had same problem two years ago. The decision was to stay with angular system and only build angular services. Neither angular factory or typescript static. The reason was we could track how service has been created and shared. (by hard)
To answer your question, angular factory is an object which still need injection base on angular system. It is good if you would like keep tight with angular.
On the other hand typescript is more general. When you call a static function, it is just a function. Like you can import it anywhere else not angular, and then use it.
Something about javascript pattern:
A common pattern for creating objects in JavaScript is the module pattern.The pattern involves returning an object from the function that will be your public API.
There is a popular variation to the module pattern called the revealing module pattern. What happens with the revealing module pattern is things start explicitly private, and then choices are made about whether they become public.

Should angular .value and .constant be used to store initialization values and utility functions?

I have a fairly complex angularJS application built with many modules, factories and controllers.
When this was started I used a parameters.js file to store initialization vars and constants used in the application. Some of these values are constants and others might be updated by the application (language, search date...).
This is not an angular element, it's just a js Object with these values inside. My question is, should this be also inside a module? is there any advantage in keeping this inside a module? if so, what`s the best way to do it, using .value and .constant? creating a factory?
Also, similar issue but in this case regarding an utility function js file, where I have some functions to parse dates and some other stuff used in different places in the application. Should this be stored in a module? and again, what would be the way to do it? a factory?
Any tip would be much appreciated.
Thanks!
Speaking only from a point of view of doing this, we use something like this, as a constants.js file:
import angular from 'angular';
export default angular
.module('app.constants', [])
.constant('someLength', 50)
.constant('someDateFormat', 'DD MMM YYYY')
.name
Inject the particular constant wherever you need in your app.

What is the correct way to extend an AngularStrap directive?

I'm looking to extend an AngularStrap directive (typeahead in this case) to have more than the provided functionality. After some research, I'm thinking the best way is to wrap the typeahead directive with my own custom directive so that I can extend it.
I've followed all 3 suggestions found here for extending an Angular directive, but none of them seem to give me access to the typeahead controller and it's public functions.
Am I going about this the wrong way? What is the best way to extend the directives for custom functionality? Any help is greatly appreciated.
In my case, I followed the approach similar to the 2nd way described there.
The difference was to use 'require' to refer to the controller of the parent directive.
How to require a controller in an angularjs directive
If you look at the source of AngularStraps typeahead directive (Link) you'll see that it has two parts, the provider; '$typeahead' and the directive 'bsTypeahead'. What I've found in the past is easiest with this library is to copy the 'bsTypeahead' directive, rename it to something else then modify it's code to do as I want. The $typeahead provider acts like the controller in this case and all other AngularStrap directives work the same.
First, the best way is definitely to wrap the Angular Strap Directive in a Directive of your own. I've done this quite a bit with different Strap Directives. Secondly it's hard to say specifically what you need to do because you didn't name any specific goals. But if you look on the doc's for the Angular Strap project you'll notice various hints. In the case of typahead you have access to the $typeaheadProvider, also this is some what speculative on my part, but typeahead has a tooltip dependency so you may be able to use the $tooltip service to fiddle with typahead in your wrapper. Finally, the Angular Strap API for typeahead is pretty robust take another look at what is already available and you maybe able to accomplish what you want/need by working with what you've already got. I.E you can specify a custom template, or specify different prefix events which after taking another look at the docs myself seems to be an interface for interacting with the tooltip scope methods. I'm sorry this couldn't be more detailed on exactly what you need to do, but hopefully it will get you moving in the right direction.

Jade Mixins in AngularJS

Hi I would like to implement Jade templates in my AngularJS project, and have mixin in my template (reusable code).
However the problem that I am facing is that we cannot use Mixin with arguments. Am I doing it correctly or is there any alternative for the same in AngularJS that I am missing?
You can create an js object from your model and pass it as strings to the mixin like the following:
+avatarRow({name: '{{avatar.name}}', uuid: '{{avatar.uuid}}', verificationCode: '{{avatar.verificationCode}}', status: '{{avatar.status}}'})
Inside the mixin you can now access e.g. #{avatar.uuid}
I considder to automate this further, because this leads to a duplication of the models code which is not so nice yet. I will share my solution if I get one :)
I figured out that mixins cannot be used in Angular as the scope is to be defined. Hence now created element directive and passed in the template (which was meant to be written in Mixin) as the templateUrl in it.

$inject Annotation on angularjs

I've see that Angular Seed comes with $inject annotation on Controllers reference, which means that I can declare the dependencies for the controller with that.
The DI documentation shows that the constructor need to be in sync with current arguments os Controller.
Also, in this documentation, it was shows one use of this annotation, usefull on minified JS sources. Like this:
var MyController = function(renamed$scope, renamedGreeter) {
...
}
MyController.$inject = ['$scope', 'greeter'];
where I found an explanation here.
So, my doubt is:
There is another use for this annotation?
On non-minified JS sources, is there any advantage or disadvantage to not use it?
Thanks in advance.
The purpose of $inject is to ensure your dependencies are injected properly if your code is minified.
There are three ways to manage dependencies in AngularJS - DI in AngularJS
Array Notation is my preferred approach as it is simpler than the $inject approach.
To answer your specific questions:
No, I am not aware of another use for $inject.
If you don't use one of the first two approaches mentioned in the linked article, your code will not function if someone minifies the source. The array notation is simple and it makes your code compatible with minifiers, so I don't know why you wouldn't use it.

Resources