How can i pas values to a function with ng-init in a angular project?
i have tried this and it works fine:
<div ng-controller="myCtrl" ng-init="myfunction(1)">
but the problem is, when i do this
<div ng-controller="myCtrl" ng-init="myfunction({{id}})">
or
<div ng-controller="myCtrl" ng-init="myfunction(id)">
it doesn't work!!
if i show the value of {{id}} in my template i get the id: 1
so the id does exist.
what is here the problem?
As Brendan Green mentioned, if id is a scope variable you don't need to pass it to the function. Would something like this work?
$scope.myfunction = function(){
// do whatever with $scope.id
}
If you really need to use it as you are your third example should work. Here is a plunker.
Created a fiddle here: http://jsfiddle.net/frishi/HB7LU/22553/
Basically, pass in the variable itself to the function and not the interpolated value, i.e. {{boo}}
<div ng-controller="MyCtrl" ng-init="boo=2">
<div ng-click="foo(boo)">Click Me</div>
</div>
In order to use myfunction in ng-init, the function should be defined in your $scopebecause ng-init evaluate expressions whatever they may be.
So here is what you should do:
HTML:
<body ng-controller="MainCtrl" ng-init='myfunction("john");'>
<p>Hello {{name}}!</p>
</body>
JS:
app.controller('MainCtrl', function($scope) {
$scope.name = 'Mike';
$scope.myfunction = function(otherName){
$scope.name = otherName;
};
});
Example
Keep in mind that it is not recommended to use ng-init this way:
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.
Related
I want to show a div according to a expression but the expression is stored in a variable in string form, is it possible to do evaluate an expression variable for ng-show / ng-hide.
like:
$scope.condition = {"SHOW":'(model1 === 'test1')'}
<div ng-show="condition['SHOW]"></div> something like this.
Try
CONTROLLER
$scope.test = 'test1';
$scope.condition = { show : ($scope.test === 'test1')};
VIEW
<div ng-show="condition.show">something like this.</div>
which is the same as
<div ng-show="condition['show']">something like this.</div>
TIP
Instead of using ng-show / ng-hide, try to use ng-if.
ng-if doesn't watch for changes on the binded variables inside this directive and can improve performance.
<div ng-if="condition['show']">something like this.</div>
Though it's already answered by other post, Just wanted to add..
Since In your question you said.. the expression is stored in a variable in string form, is it possible to do evaluate an expression variable ..
The simple answer is NO you can't evaluate angularjs expression string variable , but you can only evaluate the valid expression.(either by JS or by angular variable)
See this below code, to differentiate
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
myApp.controller('MyCtrl', function MyCtrl($scope) {
$scope.condition = {
SHOW1: "'test' == 'NOTEST'",
SHOW2: 'test' == 'test'
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-show="condition.SHOW1">
1.Not working, as it is simple string("'test' == 'NOTEST'").
</div>
<div ng-show="condition.SHOW2">
2.Working, valid boolean Angular variable
</div>
<div ng-show="'test'=='test'">
3.Working, valid boolean simple JS expression
</div>
</div>
:
Just see the code
var angApp = angular.module('angApp',[]);
angApp.controller('testController', ['$http', function ($http) {
var self = this;
self.name ='Hello';
self.btnClick=function(){
self.name ='Hello! Button Clicked';
}
}]);
<html>
<head>
</head>
<body data-ng-app="angApp" data-ng-controller="testController as model">
<div>
{{model.name}}
</br>
<input type="button" value="Click" data-ng-click="model.btnClick();"/>
</div>
</html>
Now, tell me if we avoid scope and declare controller like this way testController as model then what will be an advantage or is it only syntactic sugar?
Basically, $scope has been removed as of Angular 2. In addition to that, the angular documentation specifically recommends using this instead of $scope.
Take a look at this article for more information: https://johnpapa.net/angularjss-controller-as-and-the-vm-variable/
And also check the accepted answer on this question: 'this' vs $scope in AngularJS controllers
Once advantage I can think about is, if you have nested controllers, for instance
<div ng-controller="myFirstController as ctrl1">
<div ng-controller="mySecondController as ctrl2">
{{ctrl1.someValue}}
</div>
</div>
It is easier and more clear when trying to reference a variable on the parent controller
I'm trying to hide/show some HTML based on the existence of a function
<div ng-if="!!someFunc"> .... </div>
<div ng-if="someFunc !== undefined"> .... </div>
DEMO
Now the issue is that it doesn't matter if someFunc exists or not, it is always shown. Is there some way to make this work or should I create an other (boolean) variable on the scope ?
UPDATE: I've reproduced the issue here this time with angular v1.3.14
As others have pointed out now, in Angular 1.0, ng-if does not exist. If you have to stay with Angular 1.0, try ng-show instead.
EDIT: I wanted to make it clear that while ng-if and ng-show will both achieve what you are looking for in this case, they do behave differently behind the scenes. In short, when an ng-if expression evaluates to "false", the element will be removed from the DOM. When an ng-show expression evaluates to false, it simply changes the display property of your element. You can read more in detail here.
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
//$scope.test = function () {};
}
<div ng-controller="MyCtrl">
Is there a test function: {{!!test}}
<div ng-show="!!test">CLOSE</div>
</div>
It's something wrong with your AngularJs (too old may be).
I've updated it to new(1.3.14) and it works -
http://jsfiddle.net/HB7LU/15068/
Without any code change:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
//$scope.test = function () {};
}
You fiddle is using angular 1.0.1 which doesn't even contain ng-if (introduced in version 1.1.5). Update the external resource to a newer version or use one of the predefined fiddle frameworks (e.g. angular 1.2).
Both of those attempts work. Something must be wrong with your fiddle. Here's a full example:
var app = angular.module('app', []);
app.controller('Ctrl', function($scope) {
//$scope.someFunc = function() {};
});
<div ng-app="app" ng-controller="Ctrl">
<div>Some func: {{ someFunc ? 'yup' : 'nope' }}</div>
<div ng-if="!!someFunc">Has some func</div>
<div ng-if="someFunc !== undefined">Has some func</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.js"></script>
In my Angular project, I am using a particular value that in my controller is called something like:
$scope.feature1.items.thisItem
There's a particular <div> in my view that uses thisItem many times and it's quite messy to be referring to it as {{feature1.items.thisItem}} for example:
<div id="{{feature1.items.thisItem}}header>
<h1> You've reached the section about {{feature1.items.thisItem}} </h1>
</div>
Is there any way to rename this variable in the view? I would like to simply call it one. I've tried {{feature1.items.thisItem as one}} but that didn't work. Any other ideas?
Yes! ng-init was designed for this very purpose - aliasing another variable:
<div ng-init="thisItem = feature1.items.thisItem">
<h1> You've reached the section about {{thisItem}} </h1>
</div>
I would advise against using ng-init, it's not designed for this purpose. From Angular's 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.
You'll want to create a custom controller for this purpose. Something like the following:
module.controller('RenameController', function($scope) {
$scope.one = null;
$scope.$watch('feature1.items.thisItem', function(value) {
$scope.one = value;
});
});
Yes you can use ng-init on the top of your DOM element
<div ng-app='app'>
<div ng-controller="MyController" ng-init="myVar=feature1.items.thisItem">
{{myVar}}
</div>
</div>
I'm attempting to update my model using ng-click attached to a <p>.
I have no problem with an assignment expression outside of an ng-repeat, or with calling a scope method inside the ng-repeat. However, if I use an assignment inside the ng-repeat, it appears to be ignored. I don't see any messages reported in the Firefox console, but haven't tried setting breakpoints to see if the event is being fired.
<!DOCTYPE html>
<html>
<head>
<title>Test of ng-click</title>
<script type='text/javascript' src='http://code.angularjs.org/1.1.1/angular.js'></script>
<script type='text/javascript'>//<![CDATA[
function MyCtrl($scope) {
$scope.selected = "";
$scope.defaultValue = "test";
$scope.values = ["foo", "bar", "baz"];
$scope.doSelect = function(val) {
$scope.selected = val;
}
}
//]]>
</script>
</head>
<body ng-app>
<div ng-controller='MyCtrl'>
<p>Selected = {{selected}}</p>
<hr/>
<p ng-click='selected = defaultValue'>Click me</p>
<hr/>
<p ng-repeat='value in values' ng-click='selected = value'>{{value}}</p>
<hr/>
<p ng-repeat='value in values' ng-click='doSelect(value)'>{{value}}</p>
</div>
</body>
</html>
Fiddle is here, if you prefer (along with a couple of earlier variants).
Directive ngRepeat creates a new scope for each iteration, so you need to reference your variables in parent scope.
Use $parent.selected = value, as in:
<p ng-repeat='value in values' ng-click='$parent.selected = value'>{{value}}</p>
Note: Function call propagates due to prototypal inheritance.
If you want to learn more: The Nuances of Scope Prototypal Inheritance.
As #Stewie mentioned, $parent is one way to solve this issue. However, the recommended (by the Angular team) solution is to not define primitive properties on the $scope. Rather, the $scope should reference your model. Using references also avoids the issue (because primitive properties will not be created on the child scopes which hide/shadow the parent scope properties of the same name), and you don't have to remember when to use $parent:
HTML:
<p>Selected = {{model.selected}}</p>
<hr/>
<p ng-click='model.selected = defaultValue'>Click me</p>
<hr/>
<p ng-repeat='value in values' ng-click='model.selected = value'>{{value}}</p>
<hr/>
<p ng-repeat='value in values' ng-click='doSelect(value)'>{{value}}</p>
JavaScript:
$scope.model = { selected: ""};
...
$scope.doSelect = function (val) {
$scope.model.selected = val;
}
Fiddle.
I recently updated the wiki page that #Stewie mentioned to always recommend this approach.