I want to use the the jquery-globalize format function within a ng-bind to format a date value in a $scope field according to the current culture.
Something like this:
<div>{{Globalize.format(test.testDate, Globalize.culture().calendar.patterns.d)}}</div>
But it doesn't seem to work.
How do I accomplish this the easiest way?
Thank you
Your question mentions ng-bind but I don't see any use of it in your code. In any event, you can always use a controller to bind a variable to you views.
For example:
function HomeController() {
var vm = this;
// Any other variables here...
vm.formattedDate = Globalize.format(test.testDate, Globalize.culture().calendar.patterns.d);
}
Then in your html you could do something like:
<div ng-controller="HomeController as homeCtrl">
<p>{{ homeCtrl.formattedDate }}</p>
</div>
Or if you are using something like ui-router, you could do:
$stateProvider
.state('home', {
url: '/home',
controller: 'HomeController as homeCtrl',
template: '<p>{{ homeCtrl.formattedDate }}</p>' // Or use templateUrl.
});
Note: If you are using $scope instead of the this method, it's basically the same process except you'll just trade the vm. syntax with $scope. and you can change HomeController as homeCtrl to just HomeController.
Related
learning angular so some time things not clear when read article on angular. here i stuck to understand what is the usage or importance of this keywords Controller and controllerAs in directive.
code taken from here http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html
app.controller('SomeController', function () {
this.foo = 'bar';
});
app.directive('someDirective', function () {
return {
restrict: 'A',
controller: 'SomeController',
controllerAs: 'ctrl',
template: '{{ctrl.foo}}'
};
});
i like to know understand the importance of this two keywords in directive and they are controller: 'SomeController', and controllerAs: 'ctrl',
please tell me if we do not use these two keyword controller: 'SomeController', and controllerAs: 'ctrl', then what would happen or what would be worse ?
please help me to understand the usage or importance of this keywords controller: 'SomeController', and controllerAs: 'ctrl', in directive. thanks
You need the controller if you plan on referencing a controller object. This is how you hook it up.
The controllerAs allows you to create a variable that you can reference the controller with in lieu of using the $scope.
Refined answer:
<html ng-app="app">
<head></head>
<body>
<script src="node_modules/angular/angular.js"></script>
<script>
var app = angular.module('app', []);
app.directive('fooDirective', function() {
return {
restrict: 'A',
controller: function($scope) {
// No 'controllerAs' is defined, so we need another way
// to expose this controller's API.
// We can use $scope instead.
$scope.foo = 'Hello from foo';
},
template: '{{foo}}'
};
});
app.directive('barDirective', function() {
return {
restrict: 'A',
controller: function() {
// We define a 'vm' variable and set it to this instance.
// Note, the name 'vm' is not important here. It's not public outside this controller.
// The fact that the 'controllerAs' is also called 'vm' is just a coincidence/convention.
// You could simply use 'this.bar' if you prefer.
var vm = this;
vm.bar = 'Hello from bar';
},
// This allows us to reference objects on the controller's instance by
// a variable called 'vm'.
controllerAs: 'vm',
// Now we can reference objects on the controller using the 'controllerAs' 'vm' variable.
template: '{{vm.bar}}'
};
});
</script>
<div foo-directive></div>
<div bar-directive></div>
</body>
</html>
One of its main advantages, especially if you're new to AngularJS, is that it ensures proper data binding between child scopes.
Just play around with this code sample and try to notice something strange:
angular
.module('myApp', [])
.controller('MainCtrl', ['$scope',
function($scope) {
$scope.truthyValue = true;
$scope.foo = 'hello';
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainCtrl">
<p>Start by writing something in the first input. Then write something in the second one. Good job, you've broke AngularJS!</p>
1.
<input type="text" ng-model="foo">
<div ng-if="truthyValue">
2.
<input type="text" ng-model="foo">
</div>
<div>$scope.foo: {{ foo }}</div>
</div>
The reason behind it is that ngIf creates a child scope which inherits from the parent scope. You're basically changing the value inside ngIf's scope which doesn't affect the value from its parent scope.
Finally, I consider controllerAs syntax an important AngularJS best practice. If you get accustomed to it early in your learning process, you'd be avoiding a lot of head-scratching wondering why your code doesn't work, especially when everything seems in order.
You don't need to use both controller and controllerAs. You can use the shorthand:
controller: 'SomeController as ctrl'
The relationship is that a new instance of the controller is created and exposed to the template using the instance handle you provide as ctrl.
Where this comes in handy is if you are using nested controllers -- or using multiple instances of a controller in a view.
UPDATE TO ANSWER COMMENTS
You do not need to use controllers with AngularJS directives. Infact as of AngularJS 1.5 you should probably only use controllers when creating components rather than directives.
Directives and Components are conceptually similar. Up until AngularJS they all components would be defined as a directive.
In many ways a directive interacts with an element (like ng-href) or events (like ng-click).
The simplest way to differentiate Components and Directives is a Component will have a template.
Can't I just create a component using the directive link method?
You can, but I wouldn't recommend it unless you have a good reason. Using controllers allows you to use object oriented classes or prototypes to define the action behaviors with the template and user.
As well these controllers are extremely more easy to unit test than the directive link functions.
Check out this plunkr code
Here is my simple Directive code:
angular.module('app', [])
.directive('someDirective', function () {
return {
scope: {},
controller: function ($scope) {
this.name = 'Pascal';
$scope.color = 'blue';
},
controllerAs: 'ctrl',
template: '<div>name: {{ctrl.name}} and Color: {{color}}</div>'
};
});
And The HTML
<body ng-app="app">
<some-directive />
</body>
So, as you can see, if you need to access some variable which were defined against this keyword in the controller, you have to use controllerAs. But if it was defined against $scope object you can just access it with its name.
For example, you can get the variable color just by using {{color}} as it was defined against $scope but you have to use {{ctrl.name}} as "name" was defined against this.
I don't think there really is much difference, as this answer says,
Some people don't like the $scope syntax (don't ask me why). They say
that they could just use this
Also from their own website you can read the about the motivation behind this design choice,
Using controller as makes it obvious which controller you are
accessing in the template when multiple controllers apply to an
element
Hope it helps.
I've got a form with hundred of fields.
As part of a secondary controller I'm trying to avoid the $scope to bind the data to my view. The way I go is:
angular
.module('app')
.controller('SequencesController', SequencesController) // main controller for the view
.controller('AccordionCtrl', AccordionCtrl); // the one I'm targetting
AccordionCtrl.$inject = ['$scope','$http'];
function AccordionCtrl($scope,$http) {
this.foo = "bar";
}
I'm using this on my view but it's not working.
<div ng-controller="AccordionCtrl as acc">
Acc : {{ acc.foo }}
</div>
Using $scope does work though. Any ideas?
Extra information:
The view is binded to a main controller that's called like that in app.js
.when('/sequences', {
controller: 'SequencesController',
templateUrl: 'app/Sequences/sequences.view.html',
controllerAs: 'vm'
})
When you are trying to access to the object(controller) property: {{ acc.foo }}, which angular is doing behind is: $scope.acc.foo, because this is how angular works, you must define your variables inside the scope.
If you dont want to interfer in the showing variables, create two diferent objects inside the scope: $scope.viewVars and $scope.backVars and add them all properties you need separately.
I have an app with a directive called fightcard. In my app configuration, I'm using ui-router to change the state. This code works...
$stateProvider
.state('matches', {
url: '/matches',
template: '<fightcard matches="matches"></fightcard>'
})
But... I was wondering if there is a property on state like controller to simply pass in the directive instead of an html template. I'd like to do something like this:
$stateProvider
.state('matches', {
url: '/matches',
directive: 'fightcard',
directiveModels: ['matches']
})
The html template option isn't that terrible - it may actually be superior - just wondering if there is an alternative in more "angular way" or perhaps the html template is the preferred approach. Each match has sub views for the best of games... probably it's better to have the directives contained a simple html templates like so:
$stateProvider
.state('matches', {
url: '/matches',
templateUrl: 'partials/matches.html'
})
.state('matches.games', {
url: '/games',
templateUrl: 'partials/games.html'
})
matches.html template
<fightcard matches="matches"></fightcard>
games.html template
<h6>BEST OF 5 GAMES</h6>
<div ng-repeat="gameModel in games">
<game gamemodel="gameModel" class="centerText"></game>
</div>
Putting the directive in a template is THE way to use the directive in AngularJS.
If you wanted to get fancy, you could extend .state() using the .decorator() method of $stateProvider to parse your special config and create that template for you, but it would really be a round-about way to go about using the directive.
I would like to have a different template based on my scope.
Currently, I have only one template named : view-project.html accessible by this url : #/project/:id.
Now, I need two templates : view-project-1.html and view-project-2.html.
and I need them to keep the same url : #/project/:id
So for example, if my $scope.template = 1, I would like to use view-project-1.html with this url #/project/300. And if $scope.template = 2 I would like to use view-project-2.html with this url #/project/300
Is it possible to do that ?
app.config(function($routeProvider) {
$routeProvider
.when('/project/:id', {
templateUrl: 'template.html',
controller: 'projectcontroller'
})
});
Then in your controller:
app.controller('projectcontroller', function($scope) {
$scope.template = 2;
});
template.html:
<div ng-include="template==2?'view-project-2.html':'view-project-1.html'"></div>
DEMO PLUNKER
This, according to me, can be done in the following way :
Use ng-include to import both of your templates in the same file.
You can use ng-switch or ng-if to render one of the two templates based on the values in the route parameters.
I have a route defined as
$routeProvider.when('/:culture/:gameKey/:gameId/closed', { templateUrl: '/templates/tradingclosed', controller: TradingClosedCtrl });
I would like angular to include the "culture" parameter when requesting the template somehow, so I can serve a translated template.
Is this possible?
If I'm reading this correctly you'd like to somehow use the culture parameter from the url route to determine which location to retrieve your template.
There may be a better way but this post describes retrieving the $routeParams inside a centralized controller with ng-include to dynamically load a view.
Something similar to this:
angular.module('myApp', []).
config(function ($routeProvider) {
$routeProvider.when('/:culture/:gameKey/:gameId/closed', {
templateUrl: '/templates/nav/urlRouter.html',
controller: 'RouteController'
});
});
function RouteController($scope, $routeParams) {
$scope.templateUrl = 'templates/tradingclosed/' + $routeParams.culture + '_template.html';
}
With this as your urlRouter.html:
<div ng-include src="templateUrl"></div>
You can define the controller you want to load in your views using ng-controller and access the $routeParams for the additional route parameters:
<div ng-controller="TradingClosedCtrl">
</div>
I've posted similar question with working Plnkr example of solution like #Gloopy suggested.
The reason why you can't implement that without ng-include is that routing is done in 'configuration' block, where you can't inject any values (you can read about these blocks in Modules documentation, section Module Loading & Dependencies
If you want not to introduce new scope, you can replace ng-include with my stripped version of ng-include directive, that do absolutely same that ng-include does, but do not create new scope: source of rawInclude directive
Hope that solution will satisfy your use case.