I'm trying to add a controller in a new html content that will be added dynamically to an existing dom, but my scope is undefined. What is the best way of doing it? I'm new in Angular.
Sorry, here is my code:
var angularScript = document.createElement('script');
angularScript.setAttribute('type','text/javascript');
angularScript.setAttribute('src','https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js');
document.head.appendChild(angularScript);
jQuery('body').append("<section id='custFA'><div id='getTable' data-ng-app='custom' data-ng-controller='customController' style='overflow-y: auto !important;position:absolute; width: 300px; height: 200px; top:100px; left: 200px;'><button id='runCust' data-ng-click='codeRun()' style='top: 57px; left: 120px;'>Run</button></div></section>");
I'm inserting module and controller scripts as well, and the code in it:
Module:
setTimeout(function angularDefined(){
if(angular){
window.app = angular.module("custom",[]);
console.log("angular");
}
else{
setTimeout(angularDefined,1000);
}
},1000);
controller:
function appDefined(){
if(window.app){
window.defined=true;
console.log("appDefined");
app.controller('customController', ['$scope', function($scope) {
$scope.codeRun=function(){
console.log("check");
}
}]);
}
else{
setTimeout(appDefined,1000);
}
};
appDefined();
Thanks
You'll need to create a controller first..per the docs:
var myApp = angular.module('myApp',[]);
myApp.controller('GreetingController', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
}]);
In your html: Let your view know which controller to use. Inside of that div you will have access to any variables on $scope
<div ng-controller="GreetingController">
{{ greeting }}
</div>
Related
I am new in angularjs. I searched a lot to hide some html element on body resize but did't work. here is my controller code.
var app = angular.module('studentPage',[]);
app.controller ('studentController',function($scope, $window) {
var appWindow = angular.element($window);
appWindow.bind('resize', function () {
if($window.innerWidth < 600){
alert("hello");
$scope.ohh = true;
}
});
});
and here where i use ng-show
<div id="sidebar-wrapper" ng-show="ohh">
If you want to achieve this using AngularJS, you need to relaunch the digest cycle using $scope.$apply().
appWindow.bind('resize', function () {
if($window.innerWidth < 600){
$scope.ohh = true;
$scope.$apply();
}
});
Anyway, I think a cleaner way to do that is using CSS media queries:
#media only screen and (max-width: 599px) {
#sidebar-wrapper {
display: none;
}
}
You have to manually trigger the digest cycle using $apply() function , since what you are doing is out of angular context.Try the below code.
var app = angular.module('studentPage',[]);
app.controller ('studentController',function($scope, $window) {
var appWindow = angular.element($window);
appWindow.bind('resize', function () {
if($window.innerWidth < 600){
alert("hello");
$scope.ohh = true;
$scope.$apply()
} });});
You have to apply the scope changes by calling $scope.$apply().:-
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $window) {
var appWindow = angular.element($window);
$scope.ctrl = {};
$scope.ctrl.ohh = false;
appWindow.bind('resize', function() {
console.log($window.innerWidth);
if ($window.innerWidth < 600) {
$scope.ctrl.ohh = true;
$scope.$apply()
}
});
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<h1>THis is main content</h1><br>
<div id="sidebar-wrapper" ng-show="ctrl.ohh">This is shown after window width is less than 600
</div>
</div>
I am fairly new to AngularJS (version 1.6), i have a little mission - to implement a new popup modal when clicking an "edit" button that will have some text-boxes to edit something.
I am failing to understand how to call each of js files and because of that i don't able to finish the "mission".
The app is currently built like that (new app- so i need to construct the base to be good).
index.cshtml
Containing this code( on the portion that relevant to my mission)
<p>Edit
main.js
// application global namespace
var sulhome = sulhome || {};
sulhome.kanbanBoardApp = angular.module('kanbanBoardApp', []);
....
boardCtrl.js (portion from the start of page)
sulhome.kanbanBoardApp.controller('boardCtrl', function ($scope, boardService) {
// Model
$scope.board = {};
$scope.isLoading = false;
function init() {
...
......
There is a boardService.js also
What i am failing to understand is:
Now i need to add a popup form edit.html and a controller and a service (i want to add another controller cause i want to keep a separation and for understandability also).
How can i connect them all together?
for example: from the boardCtrl.js call the edit-controller.js and from the edit-controller, use the edit service?
This is the real eaxmple , hope it help you !
<!DOCTYPE html>
<html ng-app="injectService">
<head>
<title>Test Angular Inject Service</title>
<style type="text/css">
body{
margin:0;
padding:0;
width: 100%;
height: 100%;
position: absolute;
text-align: center;
}
body > input{
width: 25%;
height: 50px;
background: #adbfbf;
border: 0px;
margin-top: 5%;
}
</style>
</head>
<body ng-controller="testCtrl as Test">
<input type="button" name="test" value="Click me !" ng-click="Test.test()">
</body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<script type="text/javascript">
angular.module('injectService', []);
//service
(function () {
'use strict';
angular
.module('injectService')
.factory('testService', testService);
function testService() {
var service = {
getAction : getAction
};
return service;
function getAction() {
alert('test yoho !')
}
}
})();
//controller
(function () {
'use strict';
angular
.module('injectService')
.controller('testCtrl', testCtrl);
testCtrl.$inject = ['testService'];
function testCtrl(testService) {
var vm = this;
vm.test = function(){
testService.getAction();
}
}
})();
</script>
</html>
if i understand your question you want to inject your service to your controllers.
example:
sulhome.kanbanBoardApp.factory('requestService', function($http, $cookies){
var factory = {
sendRequest: function(method, url, params){
}
};
return factory;
});
And in your controller inject the service as variable dependencies
sulhome.kanbanBoardApp.controller('boardCtrl', function ($scope, boardService, requestService) {
//write your code here
//you can call your service like
requestFactory.sendRequest();
}
As I understand, your question is more about how to structure your code using controllers and services. So here is a little example of what it can be:
<head>
<!-- Import your JS files in index.html -->
<script src="topController.js/>
<script src="middleController.js/>
<script src="dataService.js/>
</head>
<div ng-app="myApp">
<div ng-controller="TopController">
Controlled by TopController
</div>
<div ng-controller="MiddleController">
Controlled by MiddleController
</div>
</div>
Where controllers and service are defined as the following:
myApp.controller('TopController', function($scope, Data) {
$scope.data = Data;
});
myApp.controller('MiddleController', function($scope, Data) {
$scope.data = Data;
});
myApp.factory('Data', function() {
obj = {
"topValue": "top",
"middleValue": "middle",
clear: function() {
this.topValue = "";
this.middleValue = "clear";
}
};
return obj;
});
Test it on JSFiddle
I want to display/update the calculation answer directly without the need of aditional buttons.
Or do i need a function and button to apply the changes?
<div ng-app="myApp" ng-controller="myCtrl">
A_Number: <input type="number" step="1" ng-model="A_Number"><br>
Display (A_Number): {{A_Number}}
<br>
square: {{square}}
</div>
controller:
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.square = $scope.A_Number * $scope.A_Number;
});
</script>
Make square as a method & use that method in interpolation directive, so that will evaluate on each digest.
Markup
square: {{square()}}
Code
$scope.square = function(){
//made error free
if(!isNaN($scope.A_Number))
return $scope.A_Number * $scope.A_Number;
return 0;
};
Add watch on A_Number to achieve the same. JSFiddle for reference -
https://jsfiddle.net/9a2xz61y/3/
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.square = 0;
$scope.$watch('A_Number', function(newValue, oldValue) {
{
if (!isNaN(newValue)) {
$scope.square = $scope.A_Number * $scope.A_Number;
}
}
});
});
I have to update a parameter of the parent controller from a nested controller.
I'm able to read the parameter, but when I change it it does not update into the view (webpage)... help plz :)
This is my js:
app.controller('signalCtrl', [ '$scope', 'DB', function($scope, service) {
this.address = null;
}]);
app.controller('reportMap', ['$scope', function($scope) {
this.updateParent = function() {
$scope.$parent.tab.address = 'something';
}
}]);
And this is my HTML:
<div ng-controller="signalCtrl as signal">
<input type="text" ng-model="signal.address">
[...]
<div ng-controller="reportMap as map">
[...]
</div>
</div>
The address property in parent controller is not bound to $scope, but to this object, so you even can't reach that property that way. I suggest you to move your updating function to parent controller:
app.controller('signalCtrl', [ '$scope', 'DB', function($scope, service) {
var self = this;
self.address = null;
self.update = function(newValue) {
self.address = newValue;
}
}]);
app.controller('reportMap', ['$scope', function($scope) {
var self = this;
self.someValue = 'something';
}]);
HTML:
<div ng-controller="signalCtrl as signal">
<input type="text" ng-model="signal.address">
[...]
<div ng-controller="reportMap as map">
<button type="button" ng-click="signal.update(map.someValue)">Click!</button>
[...]
</div>
</div>
You don't call updating function in the presented code, so I added a button to show how to use it.
use signal instead of tab
app.controller('reportMap', ['$scope', function($scope) {
this.updateParent = function() {
$scope.$parent.signal.address = 'something';
}
}]);
see this link : https://plnkr.co/edit/RhQLfBy2heecJDuCcq9s?p=preview
Ok, probably the error is into te HTML:
(function () {
var app = angular.module('segnalazioni', ['filters', 'smart-table', 'smart-table-server']);
app.controller('nuovaSegnalazioneCtrl', [ '$scope', 'DB', function($scope, service) {
var self = this;
this.activatedTab = "tab_animale";
this.chipNumber = null;
this.indirizzo = 'ind';
this.setIndirizzo = function() {
self.indirizzo = "VIA ROMA";
console.log("AGGIORNAMENTO INDIRIZZO");
}
I call setIndirizzo from the child (i don't pass a value I know, but it is not the problem): into the console i read "AGGIORNAMENTO INDIRIZZO", but the value into the VIEW does not change...
this is a link to the complete html file.
https://www.dropbox.com/s/gzlm997ub8fot7r/html.txt?dl=0
When using the $scope controller syntax, it's simple to set a value on a parent controller's object. For example
<div ng-controller="ParentController">
{{myValue.a}}
<div ng-controller="ChildController">
{{myValue.a}}
</div>
</div>
app.controller('ParentController', function($scope) {
$scope.myValue = {};
$scope.myValue.a = 1;
});
app.controller('ChildController', function($scope) {
$scope.myValue.a = 2;
});
The above outputs:
2
2
Is there a way to achieve the same functionality with the controller as syntax without referencing $scope in the child controller?
You could do it using a service, or you could do it referencing the scope.
The behavior that you are using, scope inheritance, is often referred to as an unwanted side affect. This is why isolated scopes are used with the controllerAs syntax.
In the following example you can see we achieve the same result using sharing the myValue property on the $scope along with the controllerAs syntax.
angular.module('app', [])
.controller('ParentController', ParentController)
.controller('ChildController', ChildController);
ParentController.$inject = ['$scope'];
function ParentController($scope) {
this.myValue = {};
this.myValue.a = 1;
$scope.myValue = this.myValue;
}
ChildController.$inject = ['$scope'];
function ChildController($scope) {
this.myValue = $scope.myValue;
this.myValue.a = 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
<div ng-controller="ParentController as parent">
parent: {{parent.myValue.a}}
<div ng-controller="ChildController as child">
child: {{child.myValue.a}}
</div>
</div>
</div>
This can be accomplished without $scope using a service:
angular.module('app', [])
.controller('ParentController', ParentController)
.controller('ChildController', ChildController)
.service('valueService', ValueService);
ParentController.$inject = ['valueService'];
function ParentController(valueService) {
this.myValue = {};
this.myValue.a = 1;
valueService.setValue(this.myValue);
}
ChildController.$inject = ['valueService'];
function ChildController(valueService) {
this.myValue = valueService.getValue();
this.myValue.a = 2;
}
function ValueService() {
var storedValue;
this.getValue = function() {
return storedValue;
}
this.setValue = function(value) {
storedValue = value;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
<div ng-controller="ParentController as parent">
parent: {{parent.myValue.a}}
<div ng-controller="ChildController as child">
child: {{child.myValue.a}}
</div>
</div>
</div>
if you don't like to use $scope you may pass outer controller downstream, see directives communication
No, it's not possible from within ChildController.
Don't think of ControllerAs as a newer style of $scope. Each has a different use.
ControllerAs does not publish values onto scope (it actually does - via the alias, but the alias should not be assumed to be known to a child Controller since the alias is defined in the View).
I use both where needed and I use the following convention:
app.controller("ParentCtrl", function($scope){
// $scope-inherited view model
var VM = $scope.VM = ($scope.VM || {});
// controller-specific view model
var vm = this;
VM.valueVisibleToChildControllers = "foo";
vm.valueVisibleOnlyToTheView = "bar";
});