I am using scope as 'true' in a directive. So now, this directive scope passes from parent to child, but not in reverse. I am printing now scope.name 2 times. First in parent scope, second in directive. Now I should get 2 different values. But, I am getting same scope value for both. Pl help explain!
//module declaration
var app = angular.module('myApp',[]);
//controller declaration
app.controller('myCtrl',function($scope){
$scope.name = "Peter";
});
//app declaration
app.directive('myStudent',function(){
return{
template: "{{name}}",
scope:true
}
controller: [function(){
$scope.name = "Roger"
}]
});
<body ng-app="myApp" ng-controller="myCtrl">
{{name}},
<my-student></my-student>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script>
Your controller is out of directive. I placed it inside and added $scope dependency. It works!
//module declaration
var app = angular.module('myApp',[]);
//controller declaration
app.controller('myCtrl',function($scope){
$scope.name = "Peter";
});
//app declaration
app.directive('myStudent',function(){
return{
template: "{{name}}",
scope:true,
controller: ['$scope', function($scope) {
$scope.name = "Roger"
}]
}
});
<body ng-app="myApp" ng-controller="myCtrl">
{{name}},
<my-student></my-student>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.min.js"></script>
Write your controller inside of DDO.
//app declaration
app.directive('myStudent',function(){
return{
template: "{{name}}",
scope:true,
controller: ['$scope', function($scope){
$scope.name = "Roger"
}]
}
Probably, this will solve your problem.
Easy make an object in parent controller so that it can be binded with directive
i.e var x={};
x.value=value;// that you want to pass then try accessing it.
Related
I am wondering at the dual behaviour of $scope. In the below script I am getting value of name as alert. But in my ionic app the same code alerts undefined.
I googled the problem and found this link as a solution where it states that we need to use dot(.) in order to get the value in ng-model. What is the difference between two.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a =function a(){alert($scope.name);}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input ng-model="name" ng-blur="a()">
</div>
Try changing your controller function as below:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a =function(){
alert($scope.name);
}
});
Actually it does work with Ionic,
angular.module('starter.controllers', [])
.controller('myCtrl', function($scope) {
$scope.a = function a() {
alert($scope.name);
}
})
DEMO
Solution :
"If you use ng-model, you have to have a dot in there."
Make your model point to an object.property and you'll be good to go.
Controller
$scope.formData = {};
$scope.check = function () {
console.log($scope.formData.searchText.$modelValue); //works
}
Template
<input ng-model="formData.searchText"/>
<button ng-click="check()">Check!</button>
This happens when child scopes are in play - like child routes or ng-repeats.
The child-scope creates it's own value and a name conflict is born as illustrated here:
See this video clip for more: https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s
.
And that is referred from below links :
Other Solutions
Use this keyword instead of $scope, More details
And also you can get more details from this below two discussions
Ng-model does not update controller value
Why is my ng-model variable undefined in controller?
Update Solution 1 :
Please declaring the blank object first at the top of your controller:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "";
$scope.a = function(){alert($scope.name);}
});
I hope these will be helps to you.
Try to use json object.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.user = {'name':''};
$scope.a =function a(){alert($scope.user.name);}
});
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input ng-model="user.name" ng-blur="a()">
</div>
Im new to angular js and im not able to figure out how to change the child controller scope variable from parent controller. Here is the code snippet for that:
var mainApp = angular.module("mainApp", []);
var parentCtrl = function($rootScope, $scope, shareService, $log){
shareService.setDetails($scope.pdetails);
}
var mainCtrl1 = function($rootScope, $scope, shareService, $log){
$scope.msg = "Controller 1";
$scope.details = shareService.details;//shareService.details;
}
var mainCtrl2 = function($rootScope, $scope, shareService){
$scope.msg = "Controller 2";
$scope.details = shareService.details;//shareService.details;
}
parentCtrl.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainCtrl1.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainCtrl2.$inject = ["$rootScope", "$scope", "shareService", "$log"];
mainApp.controller("parentController", parentCtrl)
.controller("mainController1", mainCtrl1)
.controller("mainController2", mainCtrl2)
.factory("shareService", function(){
var shareData = {
details : "sadfgs detaisdfadsfasdf..",
setDetails: function(value){
this.details = value;
}
};
return shareData;
});
<html>
<head>
<title>Angular JS Views</title>
<script src='lib/angular.js'></script>
<script src='js/mainApp.js'></script>
<script src='js/studentController.js'></script>
</head>
<body ng-app = 'mainApp' ng-controller='parentController' ng-strict-di>
<div ng-controller='mainController1'>
1. Msg : {{msg}}<br/>
Share Details: {{details}}<br/><br/>
</div>
<div ng-controller='mainController2'>
2. Msg : {{msg}}<br/>
Share Details: {{details}}<br/><br/>
</div>
<input type='text' ng-model='pdetails'/>
</body>
</html>
Here is the Plunker link:
https://plnkr.co/edit/hJypukqMmdHSEZMVnkDO?p=preview
In order to change value of child controller from parent controller you can use $broadcast on $scope.
syntax
$scope.$broadcast(event,data);
$broadcast is used to trigger an event(with data) to the child scope from current scope.
In child controller use $on to receive the event(with data).
Here id the code snippet:
app.controller("parentCtrl",function($scope){
$scope.OnClick=function()
{
$scope.$broadcast("senddownward",$scope.messege);
}
});
app.controller("childCtrl",function($scope){
$scope.$on("senddownward",function(event,data)
{
$scope.messege=data;
});
});
In this example I am broadcasting the event on ng-click,you can use some other custom event.like $watch on $scope.
See this example
https://plnkr.co/edit/efZ9wYS2pukE0v4JsNCC?p=preview
P.S. you can change the name of event from senddownward to whatever you want
You can access the parent's scope properties directly due to the scope inheritance:
<div ng-controller='mainController1'>
Share Details: {{pdetails}}
</div>
Your example does not work because the controllers get executed only once before the view is rendered, pdetails is empty at that moment.
To monitor the changes to pdetails, you can use $watch in the child controller:
$scope.$watch('pdetails', function(newVal) {
$scope.details = newVal;
});
I am new to AngularJS I have a problem with this code. I want to add multiple controller in single ng-app. But it execute first one. Why not second one?
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angul /1.4.8/angular.min.js"></script>
</head>
<body>
<div ng-controller="cont1">
<input type="text" ng-model="fullname">
{{fullname}}
</div>
<div ng-controller="cont2">
<input type="text" ng-model="fname">
{{fname}}
</div>
<script>
var app = angular.module("myapp", []);
app.controller('cont1', function ($scope) {
$scope.fullname = "";
});
var new = angular.module('myapp', []);
new.controller('cont2', function ($scope) {
$scope.fname = "";
});
</script>
</body>
</html>
Because you are overwriting the first myapp module when you do var new= angular.module('myapp',[]);.
Your code should be:
var app = angular.module("myapp", []);
app.controller('cont1', function($scope) {
$scope.fullname = "";
});
app.controller('cont2', function($scope) {
$scope.fname = "";
});
or
var app = angular.module("myapp", []);
app.controller('cont1', function($scope) {
$scope.fullname = "";
});
angular.module("myapp").controller('cont2', function($scope) {
$scope.fname = "";
});
The second parameter[] passed to module() makes the difference
To best way to define controllers, directives, factories etc... is
define your modules names in a separate file
app.module.js
angular.module("myapp",[]); // inside [] you define your module dependencies
for controllers create separate file (depending on your requirement even you can create 1 file for 1 controller)
some.controller.js
angular.module("myapp").controller('someCtrl'['$scope', function($scope){
}]);
angular.module("myapp").controller('someOtherCtrl'['$scope', function($scope){
}]);
NOTE:
Two types you can write controller
TYPE1 (not recomended)
.controller('ctrlName', function($scope){
});
TYPE2 (recomended)
.controller('ctrlName', ['$scope', function($scope){
}]);
Reason
So as you can see in the TYPE2 we are passing controller dependencies in an array, so when we compile our program angular will give the name as eg:a to $scope inside function() and treat it as $scope.
With the TYPE1 you need to follow specific order while defining controller dependency otherwise angular will through error because in this approach angular simply treats first dependency as $rootscope, second as $scope and so on....
For Eg:
you can't pass dependencies to your controller like this
.controller('ctrlName', function($http, $scope) {
});
this will throw error
if you define like
.controller('ctrlName', function($scope, $http) {
});
this will work fine since its in order that angular wants.
You can define multiple controllers in a single module in this way also:
angular.module("myapp",[]);
.controller('cont1',function($scope){
$scope.fullname="";
});
.controller('cont2',function($scope){
$scope.fname="";
});
When you are defining modules, don't use var. You can find some of the Angular best practices here: Angular Style Guide/Best Practices
I have a directive and a controller according to this (it's from the Angular JS Directives PacktPub book, mostly).
angular.module('myApp',[])
.directive('myIsolatedScopedDirective', function(){
return {
scope : {
'title' : '#msdTitle'
},
link: function ($scope, $element, $attrs) {
$scope.setDirectiveTitle = function (title) {
$scope.title = title;
};
}
};
})
.controller('MyCtrl', function($scope){
$scope.title = "Hello World";
$scope.setAppTitle = function(title){
$scope.title = title;
};
});
<div ng-controller="MyCtrl">
<h2>{{title}}</h2>
<button ng-click="setAppTitle('App 2.0')">Upgrade me!</button>
<div my-isolated-scoped-directive msd-title="I'm a directive within the app {{title}}">
<h4>{{title}}</h4>
<button ng-click="setDirectiveTitle('bob')">Bob it!</button>
</div>
</div>
The problem is the following:
Why the <h4>{{title}}</h4> evaluate to "Hello World" and why not "I'm a directive within the app Hello World"?
Can anybody explain this please?
Thank you.
Plunker
The reason is, you have to enter the template inside directive's template property to make it the isolated one. Right now, the directive creates an isolated scope, but it doesn't use it anywhere, because the content inside your directive tag is already evaluated in the parent scope (of MyCtrl) when the directive's link function is triggered
This is probably what to want to do
http://plnkr.co/edit/jmWrNpLFttDPhSooPF0M?p=preview
directive
.directive('myIsolatedScopedDirective', function(){
return {
scope : {
'title' : '#msdTitle'
},
replace: true,
template: '<div><h4>{{title}}</h4>' +
'<button ng-click="setDirectiveTitle(\'bob\')">Bob it!</button>',
link: function ($scope, $element, $attrs) {
$scope.setDirectiveTitle = function (title) {
$scope.title = title;
};
}
};
markup
<div my-isolated-scoped-directive msd-title="I'm a directive within the app {{title}}"></div>
jsfiddle
I have a ng-click within a directive named ball. I am trying to call MainCtrl's function test() and alert the value of ng-repeat's alignment of ball.
Why cant i recognize the MainCtrl's test function?
var $scope;
var app = angular.module('miniapp', []);
app.controller('MainCtrl', function($scope) {
$scope.project = {"name":"sup"};
$scope.test = function(value) {
alert(value);
}
$scope.test2 = function(value) {
alert('yo'+value);
}
}).directive('ball', function () {
return {
restrict:'E',
scope: {
'test': '&test'
},
template: '<div class="alignment-box" ng-repeat="alignment in [0,1,2,3,4]" ng-click="test(alignment)" val="{{alignment}}">{{alignment}}</div>'
};
});
html
<div ng-app="miniapp">
<div ng-controller="MainCtrl">
{{project}}
<ball></ball>
</div>
</div>
You need to pass the test() method from the controller into the directive...
<div ng-app="miniapp">
<div ng-controller="MainCtrl">
{{project}}
<ball test="test"></ball>
</div>
</div>
Change & to = in directive:
scope: {
'test': '=test'
}
Fiddle: http://jsfiddle.net/89AYX/49/
You just need to set the controller in your directive as:
controller: 'MainCtrl'
so the code for your directive should look like:
return {
restrict:'E',
scope: {
'test': '&test'
},
template: '<div class="alignment-box" ng-repeat="alignment in [0,1,2,3,4]" ng-click="test(alignment)" val="{{alignment}}">{{alignment}}</div>',
controller: 'MainCtrl'
};
the one way is to not isolate a directive scope...just remove the scope object from directive.
Another way is to implement an angular service and put a common method there, inject this service wherever you need it and in the directive call function that will be insight isolated scope and there call a function from directive