I have a little problem with controllers in AngularJs.
I have one controllers and some other controllers into the first controller. Basically i have this :
<body ng-app="scopeInheritance">
<div class="spicy">
<div ng-controller="MainController">
<p>Good {{timeOfDay}}, {{name}}!</p>
<div ng-controller="ChildController">
<p>Good {{timeOfDay}}, {{name}}!</p>
<p ng-if="valide()">Heelo i'm the if</p>
</div>
</div>
</div>
</body>
And my .js
var myApp = angular.module('scopeInheritance', []);
myApp.controller('MainController', ['$scope', function($scope) {
$scope.timeOfDay = 'morning';
$scope.name = 'Nikki';
$scope.testCtrl1 = true;
}]);
myApp.controller('ChildController', ['$scope', function($scope) {
$scope.name = 'Mattie';
$scope.timeOfDay = 'aternoon';
$scope.test = true;
$scope.valide = function () {
alert("i'm the function validate");
if($scope.testCtrl1 && $scope.test)
return true;
};
}]);
I want to call the function valide() to show some text. The function can return true or false depending of the value one the controller ChildController
The problem is : the function valide() is calling at every controllers.
This is normal, but how can i limite that ? The function valide() need to be call when the controller ChildController is load.
Maybe it was unclear, i made a live exemple : http://plnkr.co/edit/AM9loq4VRkL16mX8LR1v?p=preview
You can see two alert.
EDIT = valide() return true or false, depending on the value of the controllers ChildController and MainController
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>
I have a situation (modal popup) that classical link using <a href> does not work, so I need to simulate that link behavior in a <div>.
CODEPEN link
var myApp = angular.module('myApp', []);
myApp.controller('testCtrl', ['$scope', '$window', function($scope, $window) {
$scope.greeting = 'Hola!';
$scope.myAlert = function(event) {
console.log('this is the $scope.greeting');
console.log($scope.greeting);
console.log('this is the $window.location.href:');
console.log($window.location.href);
console.log('this is the event.target.dataset.href:');
console.log(event.target.dataset.href);
$window.location.href = event.target.dataset.href;
}
}]);
<div ng-app="myApp" ng-controller="testCtrl">
<div data-href="http://test.com" ng-click="myAlert($event);">CLICK ME!</div>
<div ng-click="$window.location.href='http://test.com';">DIRECTT LINK!</div>
</div>
Why the second div does nothing on click ?
NB.
I don't need to open the link in the popup or the new widow, my div is already in a popup, so I need just to open that link in the same widow like an a href does, is all I need.
In other words, I need to open a link without using a "a href". The URL is in the generated HTML, so I can't put the url in the javascript, that is an independent file...
Your code is not working because html does not recognises $window
Try this in html
<div ng-app="myApp" ng-controller="testCtrl">
<div data-href="http://test.com" ng-click="myAlert($event);">CLICK ME!</div>
<div ng-click="openLink('http://test.com');">DIRECTT LINK!</div>
</div>
in script:
var myApp = angular.module('myApp', []);
myApp.controller('testCtrl', ['$scope', '$window', function($scope, $window) {
$scope.greeting = 'Hola!';
$scope.myAlert = function(event) {
console.log('this is the $scope.greeting');
console.log($scope.greeting);
console.log('this is the $window.location.href:');
console.log($window.location.href);
console.log('this is the event.target.dataset.href:');
console.log(event.target.dataset.href);
$window.location.href = event.target.dataset.href;
}
$scope.openLink = function(link){
$window.location.href = link;
};
}]);
use <div onclick="window.location.replace('http://test.com')"></div>
I am trying to change the value of $rootScope.name that I set in the controller by another function in another controller, but when I access the $rootScope.name in another controller the value remains the same as it was set. For example:
app.controller('homectrl', function($scope, $rootScope){
$rootScope.name = "joshua";
})
app.controller('aboutctrl', function($scope, $rootScope){
$scope.send = function(newname)
{
$rootScope.name = newname;
}
})
app.controller('servicectrl', function($scope, $rootScope){
console.log($rootScope.name); // this outputs joshua instead of new name set in send function in about controller
})
You can not push the button which triggers the send() method fast enough to make the servicectrl output the new name. if you really want to see what is in $rootScope.name after you pushed the button you should observe the value or $watch it, eg. by changing the servicectrl like this:
$rootScope.$watch('name', function(newname) {
console.log($rootScope.name);
});
In a case like that I would avoid using $rootScope, but instead I would use a factory service, shared between the two controllers.
Here is a working example:
var app = angular.module('myApp',[]);
app.controller('homectrl', function($scope, NameService){
$scope.name = NameService.name;
$scope.$watch(function(){return NameService.name}, function(newValue, oldValue){
$scope.name = newValue;
});
});
app.controller('aboutctrl', function($scope, NameService){
$scope.name = NameService.name;
$scope.send = function(newname){
NameService.changeName($scope.name);
console.log('New name!', $scope.name);
}
});
app.factory('NameService', function(){
return {
name : 'joshua',
changeName : function(newName){
this.name = newName;
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="homectrl">
<h3>Home Controller </h3>
<p>{{name}}</p>
</div>
<hr>
<div ng-controller="aboutctrl">
<h3>About Controller </h3>
<input type="text" ng-model="name" />
<button ng-click="send($scope.name)">Change</button>
</div>
</div>
My problem: I have multiple instances a controller in my site. When I update 'x', only the current instance/div gets updated.
JSFiddle: http://jsfiddle.net/evgahe2u/ (simplified example, each ng-controller is in its own view.)
HTML
<!-- this is a simplified example -->
<div ng-app="myApp">
<!-- this is in view1.html -->
<div ng-controller="myController">
<input type="text" ng-model="x" /> {{x}}
</div>
<!-- this is in view2.html -->
<div ng-controller="myController">
<input type="text" ng-model="x" /> {{x}}
</div>
</div>
JS
var myApp = angular.module('myApp', []);
myApp.controller('myController', function($scope) {
$scope.x = 'test';
});
My question: How can I have it so when I update View1.html's X value, it will then update view2.html's view?
That's pretty easy.
According to me the best way to do this is to create a factory.
Let's say factory X and let's create two controllers for both views:
myApp.controller('1Ctrl', function($scope, x) {
$scope.x = x.x;
});
myApp.controller('2Ctrl', function($scope, x) {
$scope.x = x.x;
});
myApp.factory('x', function() {
return {
x: 'value'
};
});
Full Example: JSFiddle
Now if X is updated it will update in both controllers, because of the properties of an object. Both x'es on both scopes are the same x.
Broadcast from rootScope
$rootScope.$broadcast("changeXevent", dataToSend);
then handle it with an $on in the controller.
myApp.controller('myController', function($scope, $rootScope) { // inject rootscope
$scope.x = 'test';
// watch for event
$scope.$on('changeXevent', function(event, data){
$scope.x = data;
});
// watch for changes on x
$scope.$watch('x', function(newValue, oldValue){
if(newVal !== oldVal)
$rootScope.$broadcast('changeXevent', $scope.x);
});
});
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