I have 2 html file and I want to pass parameters via angular service between them.
these are the files I have:
index.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl2">
</div>
enter here
<script>
var app=angular.module("myApp");
app.controller("myCtrl2", ['$scope','$location', 'myService',
function($scope, $location, myService) {
myService.set("world");
}]);
</script>
</body>
</html>
enter2.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<script type="text/javascript" src="services.js"></script>
<div ng-app="myApp" ng-controller="myCtrl3">
hello {{x}}
</div><script type="text/javascript">
var app=angular.module("myApp");
app.controller("myCtrl3", ['$scope','$location', 'myService',
function($scope, $location, myService) {
$scope.x=myService.get();
}]);
</script>
</body>
</html>
services.js
var app=angular.module("myApp", []);
app.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
});
why can't I get "hello world" in enter2.html, but instead get "hello" (x is not found by service)...?
When you go from index.html to enter2.html the whole page loads from scratch. For the data that you are expecting to stay in the browser, you might need to use advanced angular concepts such as loading just a part of the page using ng-view.
If that's something you have already overruled, saving the data in the service somewhere (may be the browser session) before unloading (window.onunload event) the page and then loading it back from there when the service loads (window.onload event) could also work.
Here is a working example based on your code.
I kept your index.html and added ui-view to have a single page application. The app uses 'ui.router'.
In the myCtrl2 I saved the data in the service, and call it back from myCtrl3:
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
To keep things simple, I have one Javascript file:
angular.module('myApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'index.html',
controller: 'myCtrl2',
controllerAs: 'vm'
})
.state('enter2', {
url: '/enter2',
templateUrl: 'enter2.html',
controller: 'myCtrl3',
controllerAs: 'vm'
});
})
.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
})
.controller('myCtrl2', ['$scope', 'myService', function($scope, myService) {
console.log('myCtrl2');
myService.set('world');
}])
.controller('myCtrl3', ['myService', function(myService) {
console.log('myCtrl3');
var vm = this;
vm.x = myService.get();
}])
I also uses the var vm=this and ControllerAs as often recommended to avoid $scope issues.
index.html looks like below... pleaes note the ui-sref instead of href:
<div ui-view="">
<a ui-sref="enter2">Enter here</a>
</div>
enter2.html is now just the div part and your content:
<div>
Hello {{ vm.x }}
</div>
Let us know if that helps.
Additional info:
AngularJS Routing Using UI-Router
AngularJS's Controller As and the vm Variable
Sounds like you need to use a controller for your view page
https://docs.angularjs.org/guide/controller
Related
Trying to build a simple application that allows a user to upload a file, and upon clicking the 'add' button, It parses the file and displays the result within the browser.
I am using IntelliJ to generate the AngularJS application stub, and modifying it accordingly.
My attempt is below:
view1.html
<!DOCTYPE html>
<html lang="en" ng-app>
<head>
<meta charset="utf-8">
<title>My HTML File</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="../app.css">
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/ng-file-upload/ng-file-upload-shim.js"></script> <!-- for no html5 browsers support -->
<script src="bower_components/ng-file-upload/ng-file-upload.js"></script>
<!--<script src="view1.js"></script>-->
</head>
<body>
<div ng-controller="View1Ctrl">
<input type="file" id="file" name="file"/>
<br/>
<button ng-click="add()">Add</button>
<p>{{data}}</p>
</div>
</body>
</html>
view1.js
'use strict';
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', function ($scope) {
$scope.data = 'none';
$scope.add = function() {
var f = document.getElementById('file').files[0],
r = new FileReader();
r.onloadend = function(e) {
$scope.data = e.target.result;
}
r.readAsArrayBuffer(f);
}
}]);
view1_test.js
'use strict';
describe('myApp.view1 module', function() {
beforeEach(module('myApp.view1'));
describe('view1 controller', function(){
it('should ....', inject(function($controller, $rootScope) {
//spec body
// var view1Ctrl = $controller('View1Ctrl');
var $scope = $rootScope.$new(),
ctrl = $controller('View1Ctrl', {
$scope: $scope
// $User: {}
});
expect(ctrl).toBeDefined();
}));
});
});
app.js
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
'ngRoute',
'myApp.view1',
'myApp.view2',
'myApp.version'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
I am not sure where I could potentially be going wrong? I viewed quite a few questions to this and tried multiple different approaches but I cannot get this to work despite all of my tests passing.
The issue was around my view1.js file. I found the Papa Parse library extremely useful.
Here is my solution used from the open source Papa Parse community:
Papa.parse(fileInput[0], {
complete: function(results) {
console.log("Complete!", results.data);
$.each(results.data, function(i, el) {
var row = $("<tr/>");
row.append($("<td/>").text(i));
$.each(el, function(j, cell) {
if (cell !== "")
row.append($("<td/>").text(cell));
});
$("#results tbody").append(row);
});
}
});
I have set up a basic AngularJS app in VS and cannot get the ui-router functionality working. I have looked at videos, blogs, SO answers and as far as I can tell I am doing everything right, although, I am brand new to web development.
First, here is the solution structure:
and the code...
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<meta charset="utf-8" />
</head>
<body ng-app="app">
<div ui-view></div>
<script src="bower_components/angular/angular.js"></script>
<script src="app/app.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
</body>
</html>
app.js:
(function () {
'use strict';
angular.module('app', ['ui.router']);
})();
app.states.js:
(function () {
'use strict';
angular.module('app')
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/test.html',
controller: 'testCtrl',
controllerAs: 'vm'
})
});
})();
test.html:
<div>
<p>TEST PAGE</p>
</div>
testCtrl.js:
(function () {
'use strict';
angular.module('app')
.controller('testCtrl', testCtrl);
testCtrl.$inject = ['$state'];
function testCtrl($state) {
var vm = this;
var userAuthenticated = false;
init();
function init() {
$state.go('home');
};
};
})();
Can anyone see anywhere I have made a mistake?
There is a working example
I would say, that I miss these lines in your index.html
...
<script src="app/app.states.js"></script>
<script src="templates/testCtrl.js"></script>
That will loade the crucial state definition, and related controller. Check it in action here
I am just setting up a simple Angular app as I've done countless times. I added a home state and a separate state for a note taking app, yet neither states are displaying/injecting the html partials into the ui-view. I think it might be an issue with my ui-router setup, but I cannot find the issue. I console log from my controllers and they trigger correctly, so the states are clearly pointing to the right controllers.
Index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
<script src="bower_components/angular/angular.js"></script>
<script src="node_modules/angular-ui-router/release/angular-ui-router.js"></script>
<script src="app.js"></script>
<script src="factory.js"></script>
<script src="config.js"></script>
</head>
<body ng-app="myApp">
<ui-view></ui-view>
</body>
</html>
config
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateURL: './home.html',
controller: 'homeCtrl'
})
.state('list', {
url: '/list',
templateURL: '/list.html',
controller: 'listCtrl'
})
$urlRouterProvider.otherwise('/home');
});
app.js
'use strict';
var app = angular.module('myApp', ['ui.router']);
app.controller('listCtrl', function($scope, myFactory) {
console.log("list working!");
$scope.items = myFactory.items
$scope.addItem = function() {
$scope.items.unshift($scope.newItem);
$scope.newItem = "";
}
})
app.controller('homeCtrl', function($scope) {
console.log("home working!");
$scope.test = 'test'
})
My home state should load a partial containing:
<div>
<h1>Welcome!</h1>
</div>
Plunker
http://plnkr.co/edit/ngHYDtx0VBe2YPlBeJ3t?p=preview
It has to be
templateUrl: './home.html',
Also, it is not desirable to use relative paths for templates, './home.html' and 'home.html' will be cached internally as two different templates.
I am trying to set up an angularjs application properly with separate controllers.
Using $routeProvider, I want to configure the routing in order to see different views depending on the URL.
So far it's working, but only with the view depending on the last controller loaded.
Here is the code :
Routes configuration, app.js :
'use strict';
var app = angular.module('BalrogApp', ['ngRoute', 'ui.bootstrap', 'BalrogApp.controllers']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/projectsList.html',
controller : 'projectsController',
controllerAs: 'p'
})
.when('/requests', {
templateUrl: 'views/requestsList.html',
controller : 'requestsController',
controllerAs: 'r'
})
.when('/projects', {
templateUrl: 'views/projectsList.html',
controller : 'projectsController',
controllerAs: 'p'
})
.otherwise({
redirectTo: '/lol'
});
}]);
Controller 1, requestsController.js :
'use strict';
var requestsControllerModule = angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);
requestsControllerModule.controller('requestsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Request data";
this.studentMark = 75;
});
Controller 2, projectsController.js :
'use strict';
var projectsControllerModule = angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);
projectsControllerModule.controller('projectsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Project data";
this.studentMark = 75;
});
Main html page, index.html :
<!doctype html>
<html lang="en" ng-app="BalrogApp">
<head>
<meta charset="UTF-8">
<title>Student Details App</title>
<link rel="stylesheet" href="../node_modules/angular-ui-bootstrap/ui-bootstrap-csp.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
</head>
<body>
Index page :
<ng-view></ng-view>
<!--Required JS Files List :start -->
<script src="../node_modules/angular/angular.js"></script>
<script src="../node_modules/angular/angular-route.js"></script>
<script src="../node_modules/angular-ui-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="controllers/requestsController.js"></script>
<script src="controllers/projectsController.js"></script>
<script src="js/app.js"></script>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!--Required JS Files List :end -->
</body>
</html>
HTML Requests view :
Request view :
<div class="row-fluid">
<div class="span2">{{r.studentName}} </div>
<div style="display:inline-block; min-height:290px;">
<uib-datepicker ng-model="dt" min-date="minDate" show-weeks="true" class="well well-sm" custom-class="getDayClass(date, mode)"></uib-datepicker>
</div>
</div>
HTML Projects view :
Project view :
<div class="row-fluid">
<div class="span2">{{p.studentName}} </div>
<div style="display:inline-block; min-height:290px;">
<uib-datepicker ng-model="dt" min-date="minDate" show-weeks="true" class="well well-sm" custom-class="getDayClass(date, mode)"></uib-datepicker>
</div>
</div>
So the problem there changed depending on index.html :
<script src="controllers/requestsController.js"></script>
<script src="controllers/projectsController.js"></script>
Will result in a working projects view, but not working requests view. If I include the requests controller after, this will be the opposite.
Also, is there a problem with my ControllerAs syntax ? Since I'm using it from the $routeProvider, it's not working at all.
When you do angular.module('BalrogApp.controllers', ['ngRoute', 'ui.bootstrap']);, it creates a new module. What you really want is to reference an existing module, otherwise you will overwrite it every time you load a controller JavaScript file.
Change you controllers initialization to this:
angular.module('BalrogApp').controller('requestsController', function () {
// ...
});
And
angular.module('BalrogApp').controller('projectsController', function () {
// ...
});
This way, you'll be referencing an existing module and will not overwrite it every time.
In your app.js you have already defined the dependencies of modules and by defining again in the controllers you are overriding it, Fix the module line in your controllers as shown below :
Requests View :
'use strict';
var requestsControllerModule = angular.module('BalrogApp.controllers', []); // Fix This..
requestsControllerModule.controller('requestsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Request data";
this.studentMark = 75;
});
Projects view :
var projectsControllerModule = angular.module('BalrogApp.controllers', []); // Fix this..
projectsControllerModule.controller('projectsController', function($rootScope, $scope, $location, $routeParams) {
this.studentName = "Project data";
this.studentMark = 75;
});
I would like to use i18n and i10n in my Angular app.
I read that Angular-translate can help with this, however, it doesn't work for me.
In my index.html:
<!DOCTYPE html>
<html ng-app="eApp">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="../common/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="../common/css/style.css" />
<title></title>
</head>
<body ng-controller="AppCtrl">
<div id="container" ng-view></div>
<!--- Libs Js files --->
<script type="text/javascript" src="../vendor/angularjs/angular.min.js"></script>
<script type="text/javascript" src="../vendor/angularjs/angular-route.min.js"></script>
<script type="text/javascript" src="../vendor/angularjs/angular-translate.min.js"></script>
</body>
</html>
In my eApp.js:
var eApp = angular.module('elbitApp', ['ngRoute', 'ui.bootstrap', 'config', 'pascalprecht.translate']);
// configure our routes
eApp.config(["$routeProvider",
function ($routeProvider) {
$routeProvider
// route for the home page
.when('/c', {
templateUrl: 'c/partials/c.html',
controller: 'CController'
})
// route for the about page
.when('/de', {
templateUrl: 'd/partials/dE.html',
controller: 'DEController',
resolve: {
data: function (DDataService) {
return DDataService.loadData().then(function (response) {
return response.data;
});
}
}
})
// route for the contact page
.when('/di', {
templateUrl: 'd/partials/di.html',
controller: 'DIController',
resolve: {
data: function (DDataService) {
return DDataService.loadData().then(function (response) {
return response.data;
});
}
}
}).otherwise({
redirectTo: '/di'
});
}]).config(["$httpProvider",
function ($httpProvider) {
// Configure the $httpProvider to parse date with date transformer
$httpProvider.defaults.transformResponse.push(function (responseData) {
convertDateStringsToDates(responseData);
return responseData;
});
}]).config(["$translateProvider",
function ($translateProvider) {
$translateProvider.translations('en', {
"TITLE": 'Hello',
"FOO": 'This is a paragraph.',
"BUTTON_LANG_EN": 'english',
"BUTTON_LANG_DE": 'german'
});
$translateProvider.translations('de', {
"TITLE": 'Hallo',
"FOO": 'Dies ist ein Paragraph.',
"BUTTON_LANG_EN": 'englisch',
"BUTTON_LANG_DE": 'deutsch'
});
$translateProvider.preferredLanguage('en');
}]);
// main controller that catches resolving issues of the other controllers
eApp.controller('AppCtrl', function ($rootScope) {
$rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
alert("Cant resolve the request of the controller "); //TODO: add URL + additional data.
})
});
In this file I defined my app and added the $translateProvider and two dictionaries.
Afterwards I got to my deController.js:
eApp.controller('DispatcherEventsController', ['$scope', '$route', '$translate',
function($scope, $route, $translate){
var data = $route.current.locals.data;
$scope.title = $translate.instant("FOO");
$scope.switchLanguage = function(languageKey){
$translate.use(languageKey);
};
}]);
In de.html I added a h1 tag with FOO and in a click I would like to change to German:
<h1>{{title |translate}}</h1>
<h1 translate="{{title}}"></h1>
<button type="button" id="searchButton" class="btn btn-default" ng-click="switchLanguage('de')">German</button>
I don't get any problem, but nothing happens. I expected that the English title will be converted to German title.
What can I do to make this work?
It works well for me. Here is a jsFiddle DEMO.
In this case, you want to bind $scope.title with translation key "FOO".
You should change the value of $scope.title dynamically in the switchLanguage function. Then view will be updated accordingly.
//default value
$scope.title = $translate.instant("HEADLINE");
$scope.switchLanguage = function(key){
$translate.use(key);
$scope.title = $translate.instant("HEADLINE");
}
In my opinion, maybe use translation key is a better way than scope data binding. You don't have to maitain the value of key manually.
<h1>{{'FOO' | translate}}</h1>
According to the error msg you provided, maybe you could check if there is any typo syntax in your controller.
Should be
$translate.use(languageKey)
Not
$translate.uses(languageKey)
Though not directly related to your question - you must remember to set the preferred language in the translations.js file, or whatever its name is that you define your key-value translations. Otherwise it will just default to whatever the key is.
...
GREETING: 'Hello World!',
...
$translateProvider.preferredLanguage('en');
Without this line, when doing this:
<h2>{{'GREETING'|translate}}</h2>
Would appear as just GREETING instead of the 'Hello World.'