AngularJS broadcast from $rootScope to modal window scope - angularjs

Is there any way to broadcast from $rootScope to modal window $scope?
My $rootScope is ApplicationController and I'm listening in there to socket.io event. When I handle this event I want to $broadcast to ChatController (modal window) $scope (which might be already opened so resolve won't help me here).
A quick example to demonstrate this issue:
index.html:
<!DOCTYPE html>
<html ng-app="App">
<head>
<link data-require="bootstrap-css#3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script data-require="angular.js#1.3.0-beta.5" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script data-require="jquery#*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script data-require="bootstrap#3.1.1" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script data-require="angular-ui-bootstrap#0.11.0" data-semver="0.11.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="ApplicationController">
<h1>Hello Plunker!</h1>
<input type="button" value="open modal" ng-click="openModal()">
<div ng-controller="NotModalController">
{{fields.field1}}
</div>
</body>
</html>
script.js:
(function() {
var app = angular.module("App", ["ui.bootstrap"]);
app.controller("ApplicationController", function($scope, $modal) {
$scope.openModal = function() {
var modalInstance = $modal.open({
templateUrl: 'chat.html',
controller: 'ModalController',
size: 'lg',
resolve: {
}
});
modalInstance.result.then(function() {
console.log('modal closed');
}, function() {
console.log('modal dismissed');
});
setTimeout(function() {
console.log('broadcasting event');
$scope.$broadcast('someEvent', 'broadcasted value');
}, 3000);
};
});
app.controller("NotModalController", function($scope) {
$scope.fields = {
field1: 'initial'
};
$scope.$on('someEvent', function(event, args) {
$scope.fields.field1 = args;
});
});
app.controller("ModalController", function($scope) {
$scope.fields = {
field1: 'initial'
};
$scope.$on('someEvent', function(event, args) {
$scope.fields.field1 = args;
});
});
})();
modalTemplate.html
<div>
{{fields.field1}}
</div>
the plunkr url : http://plnkr.co/edit/9xpwmleZJnAG66cGWcYO

Think you should use $rootScope.$broadcast instead $scope.$broadcast

Related

AngularJS compile dynamic content

Consider the following webpage:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>First Test</title>
<script src="jquery-3.2.1.min.js"></script>
<script src="angular.js"></script>
<script>
var myApp = angular.module('myApp',[]);
function addDiv(){
var div = "<script> \
myApp.controller('myController', function ($scope) { \
$scope.testDynamic = function(){ \
alert('it works!'); \
} \
}); \
<\/script> \
<div ng-controller=\"testController\">{{\"TEST\"}}<button ng-click=\"testDynamic();\">Click Me!</button></div>";
$("body").append(div);
// How to use $compile here???
}
</script>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
</head>
<body>
<div>{{"AngularJS"}}</div>
<button onclick="addDiv();">addDiv</button>
</body>
</html>
When the content is appended to the body, how I can load/compile the angularjs part? I have tried to use $compile like:
angular.element('body').injector().invoke(function ($compile, $rootScope) {
$rootScope.$apply(function() {
var scope = angular.element(div).scope();
$compile(div)(scope);
});
});
But without any success. I get the error: "Error: [ng:areq] Argument 'scope' is required..."
Someone can help?
After some tries, I got it working. It was simpler than I thought. After the definition of angular module, I need to add this configuration part:
myApp.config(['$controllerProvider','$compileProvider', '$filterProvider', '$provide', function($controllerProvider, $compileProvider, $filterProvider, $provide) {
myApp.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
Then to register the controller coming from ajax:
myApp.register.controller('myController', function($scope) {
$scope.name = "Pippo";
$scope.age = 18;
$scope.go = function(){alert('It works!')}
});
Then, at the success call from ajax add the compile part:
$compile($('#remdiv'))($scope);
Here's the complete code:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>First Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script>
myApp = angular.module('myApp',[])
.controller("mainCtrl", function($scope, $http, $compile, $rootScope){
$scope.addDiv = function(){
var ajaxhtmlcode = '<script> \
myApp.register.controller(\'testc\', function($scope) { \
$scope.name="Pippo"; \
$scope.age=18; \
$scope.go = function(){alert(\'It works!\')} \
}); \
<\/script> \
<div id="remdiv" ng-controller="testc"> \
{{msg}} \
Name:<input ng-model="name" /> \
Age:<input ng-model="age" /> \
<button ng-click="go();">Go!<\/button> \
<\/div>';
$('body').append(ajaxhtmlcode);
$compile($('#remdiv'))($scope);
}
});
myApp.config(['$controllerProvider','$compileProvider', '$filterProvider', '$provide', function($controllerProvider, $compileProvider, $filterProvider, $provide) {
myApp.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
}
]);
</script>
</head>
<body ng-controller="mainCtrl">
<div>{{"AngularJS"}}</div>
<button ng-click="addDiv();">addDiv</button>
</body>
</html>
1- First of all you have incorrect controller naming, you inject a controller named myController but you trying to call controller named testController
2- you can't declare new controller with this way you have to declare it first and inject the template only via compile method
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>First Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
var myApp = angular.module('myApp',[])
.controller("mainCtrl",function($compile,$scope,$rootScope){
$scope.addDiv=function(){
var div = $compile("<div ng-controller=\"test\">{{\"TEST\"}}<button ng-click=\"testDynamic();\">Click Me!</button></div>")($rootScope);
$("body").append(div);
// How to use $compile here???
}
})
.controller('test', function ($scope) {
$scope.testDynamic = function(){
alert('it works!');
}
});
</script>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
</head>
<body ng-controller="mainCtrl">
<div>{{"AngularJS"}}</div>
<button ng-click="addDiv();">addDiv</button>
</body>
</html>
Thank you Peter. The first was a copy-paste mistake. I am new in Angular and I am just trying to understand how it works. Your solution works, but what I wanted to point our is this:
What about if I can't define the controller "test" BEFORE? I mean, if the controller definition comes from a html ajax request (I mean if the div variable is populate by an ajax request, controller definition included). That's why I have put the script definition inside the div variable.
Taking back my example...main page:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>First Test</title>
<script src="jquery-3.2.1.min.js"></script>
<script src="angular.js"></script>
<script>
var myApp = angular.module('myApp',[])
.controller("mainCtrl",function($compile,$scope,$rootScope, $http){
$scope.addDiv=function(){
$http({
url: "test.php",
method: "post",
data: '',
responseType: 'text',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(function successCallback(response) {
$('body').append(response.data);
}, function errorCallback(response) {
alert(response.statusText);
});
}
});
</script>
<link href="bootstrap.css" rel="stylesheet" />
<link href="bootstrap-theme.css" rel="stylesheet" />
</head>
<body>
<div ng-controller="mainCtrl">{{"AngularJS"}}
<button ng-click="addDiv();">addDiv</button>
</div>
</body>
</html>
Where test.php is simply:
<script>
myApp.controller('myController', function ($scope) {
$scope.name = "Pippo";
$scope.age = 10;
});
</script>
<div ng-controller="myController">
Name:<input ng-model="name" />
Age:<input ng-model="age" />
</div>
If I run this code, I can't see the input (name and age) populated as defined in "myController"...

side navigation does not work in angular code

My code is as shown below:
index.html
<!DOCTYPE html>
<html>
<head>
<title>quflip</title>
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="css/login.css">
</head>
<body ng-app="quflipMobWeb">
<ng-view></ng-view>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="js/services.js"></script>
<script src="js/controller/loginController.js"></script>
<script src="js/controller/homeController.js"></script>
<script src="js/app.js"></script>
<script src="js/controller/driverController.js"></script>
<script src="js/controller/driversController.js"></script>
<script>
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
}
</script>
</body>
</html>
home.html
<div>
<div id="mySidenav" class="sidenav">
×
About
Services
Clients
Contact
</div>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>
</div>
homeController.js
angular.module('quflipMobWeb.homeController', []).
controller('homeController', function($scope) {
// console.log("home called");
});
app.js
angular.module('quflipMobWeb', [
'quflipMobWeb.services',
'quflipMobWeb.controllers',
'quflipMobWeb.login',
'quflipMobWeb.homeController',
'ngRoute'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when("/home", { templateUrl: "template/home.html", controller: "homeController" }).
when("/login", { templateUrl: "template/login.html", controller: "loginController" }).
otherwise({ redirectTo: '/login' });
}]);
For detailed code, I have given my repository url here:
https://github.com/mrugesh008/testRepo.git
This is the website which I am following for achieving the effect
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sidenav
Your code almost works well. you can just add ng-style:
app.controller('homeController', function($scope) {
console.log("home called");
$scope.myStyle = {
width: '0px'
};
$scope.openNav = function() {
$scope.myStyle.width = '250px';
}
$scope.closeNav = function() {
$scope.myStyle.width = '0px';
}
});
Home.html
<div>
<div id="mySidenav" class="sidenav" ng-style="myStyle">
×
About
Services
Clients
Contact
</div>
<span style="font-size:30px;cursor:pointer" ng-click="openNav()">☰ open</span>
</div>
Demo Plunker

How to load controller in Angular 1.6 (Argument 'simpleController' is not a function, got undefined)

I am trying to learn AngularJS, I have View1 which uses simpleController, but AngularJS (1.6) is throwing an error and I can't find the right syntax to make it work.
My Repository is: https://github.com/tommcclean/Learning_Angular.
Error: ng:areq. Bad Argument. Argument 'simpleController' is not a
function, got undefined
View1 contains...
<div ng-controller="simpleController as ctrl">
<h2>View One</h2>
<p>{{ ctrl.testValue }}</p>
</div>
simpleController contains...
"use strict";
(function () {
angular.module('demoApp').controller('simpleController', []);
function simpleController() {
var self = this;
self.testValue = "Test Value";
self.updateValue = function () {
self.testValue = "Test Value Updated";
};
return self;
};
});
demoApp is created by my routes.js file which is loaded first.
"use strict";
var app = angular.module('demoApp', ["ngRoute"]);
app.config(function ($routeProvider) {
$routeProvider
.when('/view1',
{
controller: 'simpleController',
templateUrl: '../views/view1.html'
})
.otherwise({ redirectTo: '/view1' });
});
My main page which is the home of my "spa" contains...
<!DOCTYPE html>
<html>
<head>
<title>Sample Demo Application</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
</head>
<body ng-app="demoApp" class="container">
<h1>Welcome to my Sample Application</h1>
View 1
<div ng-view></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script src="../app/initialise/routes.js"></script>
<script src="../app/controllers/simpleController.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
</body>
</html>
Check out the .controller definition should have the function not an empty array as the second argument.
"use strict";
(function () {
angular.module('demoApp').controller('simpleController', simpleController);
function simpleController() {
var self = this;
self.testValue = "Test Value";
self.updateValue = function () {
self.testValue = "Test Value Updated";
};
return self;
};
});
"use strict";
var app = angular.module('demoApp', ["ngRoute"]);
app.config(function ($routeProvider) {
$routeProvider
.when('/view1',
{
controller: 'simpleController',
controllerAs: 'ctrl',
templateUrl: '/view1.html'
})
.otherwise({ redirectTo: '/view1' });
});
(function () {
function simpleController() {
var self = this;
self.testValue = "Test Value";
self.updateValue = function () {
self.testValue = "Test Value Updated";
};
return self;
};
angular.module('demoApp').controller('simpleController', simpleController);
})();
<body ng-app="demoApp" class="container">
<h1>Welcome to my Sample Application</h1>
View 1
<div ng-view></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script type="text/ng-template" id="/view1.html">
<div>
<h2>View One</h2>
<p>{{ ctrl.testValue }}</p>
</div>
</script>
</body>

Components in Angular 1.5.8 and 1.6.1

Here is my very simple code:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
</head>
<body>
<t-component test="test">
<div >
{{test}} John
</div>
</t-component>
<script>
angular.module('myApp', []).
component('tComponent', {
bindings: {
test: '='
},
controller: function() {
var self = this;
self.test='Hello';
}
});
</script>
</body>
</html>
I am getting Hello John only when using Angular 1.5.8. What do I have to do as to make the above to work with Angular 1.6.1? What am I missing?
I have this code working like that:
<t-component test="'test'"></t-component>
<script>
angular.module('myApp', []).
component('tComponent', {
template:'{{vm.test}} John',
bindings: {
test: '<'
},
controller: function() {
var self = this;
self.$onInit = function(){
// self.test ='hello'; //if you don`t want to use binding
}
},
controllerAs: 'vm'
});
</script>
<body>
<t-component test="'Hello'"></t-component>
<script>
angular.module('myApp', []).
component('tComponent', {
template: `
{{$ctrl.test}} John
`,
bindings: {
test: '='
},
controller: function() {
}
});
</script>
</body>
Then in controller you can change value of binding.
self.$onInit = function(){
self.test ='I am changed';
}

How to use window.onload in angular js controller?

How to use window.onload function inside a controller.
window.onload= function() {
console.log("Hi Page loaded")
};
The controller is not applicable for the full page.
I want to execute a function after my controller loads at-least.
You can use ng-init and invoke your necessary function using the same directive
var app = angular.module('DemoApp', [])
app.controller('akuaController', function($scope) {
$scope.load = function() {
alert("Window is loaded");
}
});
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.4.7" data-semver="1.4.7" src="https://code.angularjs.org/1.4.7/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.4.7/angular-filter.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="DemoApp" ng-controller="akuaController">
<div ng-init="load()">
</div>
</body>
</html>
Changing the example from Angular $window
Your Controller
angular.module('windowExample', [])
.controller('ExampleController', ['$scope', '$window', function($scope, $window) {
$scope.greeting = 'Hello, World!';
$scope.doGreeting = function(greeting) {
// This would be a starting point
$window.onload(greeting);
};
}]);
Your markup
<div ng-controller="ExampleController" ng-init="ExampleController.doGreeting()">
</div>
//inside your controller
$scope.$on('$viewContentLoaded', function() {
// write here
// either methods or variables
});

Resources