Angular.js provides a banch of global functions like angular.lowercase, angular.isArray etc.
Suppose I have a string in my scope:
function MyController($scope) {
$scope.myString = "TEST"
}
Calling angular.lowercase has no effect:
{{lowercase(myString)}}
{{angular.lowercase(myString)}}
How can I call such function in my template?
UPDATE
Example with angular.isArray
<div ng-show="isArray(myVar)">...</div>
The expression in the {{}} is not actual javascript although it looks that way - it's an angularjs expression. For this reason not everything will be available to you.
charlietfl is right that your particular case can be solved with an existing filter. Not every angular.* function is exposed this way, however, in which case you should create your own custom filters.
Filters are cleanest but as a dirty workaround you could also just have the following line in your controller:
$scope.lowercase = angular.lowercase; // not angular.lowercase()
Related
I want to use something like below:
<span ng-bind="rep.newDate.match('.*FNFx.*')?'NotAvailable':(rep.value===''?'?':rep.value)"></span>
But it's not working. How to correct it?
I problem I feel is you cannot use JavaScript's match function as it is in the template. This is because it is not in angular's scope.
To resolve this, create a function in your controller for doing the regex part as follows:
$scope.matchPattern = function(date) {
return date.match('.*FNFx.*')
}
and change your ng-bind to:
ng-bind="matchPattern(rep.newDate)?'NotAvailable':(rep.value===''?'?':rep.value)"
I am trying to pass a function from a controller to a directive so an event fired from the directive could cause a refresh in a different controller.
controllers.controller('UserCtrl', function ($scope) {
$scope.name="Name";
$scope.test = function (t) {
console.log("Inside "+t+" "+$scope.name)
return $scope.test2();
};
$scope.test2 = function(){
return 2;
}
}
<my-test-directive respond="test">
This seems to work fine but when I change it to try and match the Google Angular conventions I get an undefined error on return this.test2();. Here is a plunker with the failing version.
Using the "Google Angular style" how would I handle this?
Please see here: http://plnkr.co/edit/Mugs2C7UOjlXx1L3LsMP?p=preview
You need to change few things :
To call function from directive you should use '&' instead '='
In your html change respond="userController.test" to respond="userController.test(msg)"
Finally you should pass object to function instad of string change scope.respond("So I should be getting inside"); to scope.respond({msg:"So I should be getting inside"})
I hope that will helps.
When you pass a function in javascript the context of the function gets lost so the this keyboard won't work anymore. If you want to pass your test function you need to wrap it in a function that is bound to userCtrl. You can do this with bind() by adding the following line to your controller's constructor and passing boundTest to your directive instead of test
this.boundTest = this.test.bind(this);
Note that bind() was introduced in ES5 so it won't work in IE8
Here is a working plunker http://plnkr.co/edit/BTuwTFf2XsmrR3As4x1x?p=preview
Here is what I came up with
Thanks to rob for the idea, I don't know that I like this though for two reasons...
1.) I cannot seem to use prototype, limiting my inheritance options (as I understand it)
2.) This looks rather hacky
$scope.userController.test2();
Depending on the vote count and comments will depend what I mark as the answer so please provide feedback
In angularJs is possible to watch a global variable?
I set a window.test variable from legacy code, then I need to watch that variable to know if it exists.
I've tried something like
$window.$watch("test" , function(n,o){
//some code here...
}
Somewhat. You can if you include the Angular $window service (which is safer, as explained in the docs, than accessing window directly):
app.controller('myCtrl', function ($scope,$window) {...}
And then use a watch function as the first parameter to your $watch like so:
$scope.$watch(
function () {
return $window.test
}, function(n,o){
console.log("changed ",n);
}
);
demo fiddle
But note that the $watch won't execute until something triggers Angular to do a $digest. One possible way to do that is to wrap your legacy code in a $scope.$apply or trigger a $digest once the legacy code has exectuted. Here's some good documentation on this.
Basically whenever a change happens outside of angular (for instance this is a common issue when jQuery causes the change) something has to tell Angular to go see if something changed. It's one way Angular maintains reasonable performance.
It's probably the best to illustrate my question with an example.
Here is a template snippet:
<div class="title">{{action}} Location</div>
Double curly markup tells AngularJS to evaluate action against the current scope AND to create a data-binding to action.
Is there a way to tell AngularJS to evaluate action once and be done (ie. I don't need the data-binding/watch)?
I cannot find the direct support of interporate once feature in Angular.
But you can easily work around it by using separate variable which gets
copied from action once and never changes afterwards.
In your controller:
$scope.action0 = action;
in your template:
<div class="title">{{action0}} Location</div>
EDIT : Another way is to define a directive which interpolates once
and leave it alone.
http://plnkr.co/edit/6Ul1QgqhNH0bqK2af2Jo?p=preview
js:
app.directive('staticBind', function(){
return function(scope, elem, attrs) {
elem.text( scope[ attrs.staticBind ]);
};
});
template:
<span static-bind="variable"></span>
I have found Pasvaz's bindonce module, another solution that suits better for my need, from the Angular mailing list.
UPDATE 10/27/2014: Starting from v1.3, AngularJS core supports one-time binding
I faced the same problem. I want to evaluate the expression but i dont want to display it. so i found one solution, just put your expression that you want to evaluate in ng-hide div and set ng-hide to false like
<div ng-hide="true">{{your expression here}}</div>
it will execute the expression without displaying the content
Use angular.copy when you set the scope to be used in that template. Angular wont watch a var set to a copy. angular.copy is used to store the value of the current value of a watchExpression for later comparison.
Using the Angular UI Select2 directive, with tags defined on an input field. If the input is itself inside a custom directive, then it is not initialised correctly and the console gives an error:
query function not defined for Select2 tagging
I suspect this might be to do with the order in which the directives are compiled / linked vs when the select 2 function is called.
Maybe there is a simple workaround, perhaps using the compile function or a directive controller instead of a link function? Or maybe it is an issue with the Angular UI select2 directive.
I have made a plunker that displays the problem:
http://plnkr.co/edit/myE5wZ
So my question is - How do you get get select2 tags working from inside a custom Angular directive?
In the end I managed to find a solution I was happy with involving nesting two directives, that way the logic can be encapsulated inside the parent directive (not spilling out into the controller).
A Plunker of my solution is here for anyone who may stumble across the same issue:
http://plnkr.co/edit/ZxAPF5BzkgPtn9xddCRM
I just encountered this today and summarily realized the fix:
PostLinking functions are executed in reverse order (deepest grandchild to greatest grandparent).
Put your custom modal's code (or anything that sets $scope data for use in its children) inside a PreLinking function. PreLinking functions go from parent to child, and all PreLinking functions are performed before the PostLinking functions.
I had a similar issue. Your solution works but IMHO I think an even better solution is to use the controller function instead of the link function inside the directive. Doing this you do need nested directives.
By using the controller function instead of the link function in the directive it's working. Example:
function myFunction() {
var dir = {};
dir.scope = { myModel: '=' };
dir.restrict = 'E';
dir.templateUrl = 'myTemplate.html';
dir.replace = true;
dir.controller = function ($scope) {
$scope.myVar = ...;
};
return dir;
};
I have this error too. My short solution:
<input type="hidden"
name="citizenship"
class="form-control input-sm col-sm-10"
style="width:500px"
multiple
ui-select2="params.options.citizenshipOptions"
ng-model="cvLang.content.citizenship"
ng-repeat="a in [1]"
/>
ng-repeat="a in [1]" is a magical thing!!! It is not clear for me a logic of a context, but this is working. May be this can help?