I'm facing some problems with my simple code (study), i really need some help to fix this.
First of all i have a php file who provides a json.
app.php
<?php
$dbh = new PDO('mysql:host=localhost;dbname=caio', 'root', '');
$a = $dbh->query("SELECT * FROM usuario");
$b = json_encode($a->fetchAll(PDO::FETCH_ASSOC));
echo $b;
?>
It's a simple json with id, name and surname
Also i have a Js file to get this.
app.js
var meuApp = angular.module('meuApp', ['ui.router']);
meuApp.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('usuarios.detail', {
url: "/usuarios/{id}",
templateUrl: 'uDetail.html'
});
});
meuApp.controller('userCtrl', ['$scope', '$http', function ($scope, $http) {
$http.get('app.php')
.success(function(data) {
$scope.usuarios = data;
console.log(data);
//just checking in the console...
var id = data[0].id
console.log(id);
var nome = data[0].nome
console.log(nome);
});
}]);
and finally my html file
<html ng-app="meuApp" lang="pt">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="userCtrl">
<ul>
<li ng-repeat="usuario in usuarios">
<a ui-sref="usuarios.detail">{{usuario.nome}}</a>
</li>
</ul>
</div>
</body>
If i want to show, ok the code is working, but i want to click in each name and then the template shows me the id, name and surname of this "person". That's my problem.
Thank you guys.
Here you need to pass person object from one state to another state.
For that you can use params attribute of ui-router. When you click any perticular person at that time you need to pass id also while routing from one state to another because you already configure in url "/usuarios/{id}".
ui-router will match that property from params and will set in url.
Now you can successfully pass clicked object from one state to another. Get that object with $stateParams service of ui-router in controller of usuarios.detail state so that you can display in uDetail.html
meuApp.config(function($stateProvider, $urlRouterProvider,$stateParams){
$stateProvider
.state('usuarios.detail', {
url: "/usuarios/{id}",
params: {
id: null,
person:null
},
templateUrl: 'uDetail.html',
controller: function($scope, $stateParams) {
$scope.portfolioId = $stateParams.id;
$scope.person = $stateParams.person;
console.log("State parameters " + JSON.stringify($stateParams));
}
});
});
and in your template where you are showing the list.
<ul>
<li ng-repeat="usuario in usuarios">
<a ui-sref="usuarios.detail({ id:usuario.id,person:usuario})">{{usuario.nome}}</a>
</li>
</ul>
See above code which I gave for your reference.
You can see this Demo for in detail idea of ui-router.
You need some minor changes in order to get your code working, check the files bellow:
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="userCtrl">
<ul>
<li ng-repeat="user in users">
<a ui-sref="users.detail({id: user.id, user: user})">{{user.name}}</a>
</li>
</ul>
</div>
<div ui-view></div>
</body>
app.js
var app = angular.module('app', ['ui.router']);
app.config(function($stateProvider) {
$stateProvider
.state('users', {
abstract: true,
url: 'users',
template: '<div ui-view></div>'
})
.state('users.detail', {
url: '/:id',
templateUrl: 'users.detail.html',
params: {
user: null
},
controller: function($scope, $stateParams) {
$scope.user = $stateParams.user;
}
});
});
app.controller('userCtrl', ['$scope', '$http',
function($scope, $http) {
// replace this with your service call
$scope.users = [{
id: 1,
name: 'john',
surname: 'doe'
}, {
id: 2,
name: 'mary',
surname: 'poppins'
}];
}
]);
user.detail.html
<fieldset>
<div>
<label>id: </label> {{user.id}}
</div>
<div>
<label>name: </label> {{user.name}}
</div>
<div>
<label>surname: </label> {{user.surname}}
</div>
</fieldset>
Related
I'm attempting to make a simple Hello World page with an inline template defined as home.html. The routing used is ui.router, and when the code is run I receive an infinite loop of
GET /home.html 404 0.868 ms - 1076
which indicates to me that angular can't find the home.html template that was defined.
app.js
var app = angular.module('HelloWorld', ['ui.router']);
app.controller('MainCtrl', [
'$scope',
'posts',
function($scope, posts){
$scope.test = 'Hello world!';
$scope.posts = posts.posts;
$scope.addPost = function(){
if(!$scope.title || $scope.title === '') { return; }
$scope.posts.push({
title: $scope.title,
link: $scope.link,
upvotes: 0
});
$scope.title = ''; //Set title to empty
$scope.link = ''; // Set link to empty
};
$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
};
}]);
app.factory('posts', [function(){
var o = {
posts: [
{title: 'post 1', upvotes: 5}
]
};
return o;
}]);
app.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'home.html',
controller: 'MainCtrl'
});
$urlRouterProvider.otherwise('home');
}]);
index.ejs
<!DOCTYPE html>
<html ng-app="HelloWorld">
<head>
<title>Hello World</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="javascripts/app.js"></script>
<style> .glyphicon-thumbs-up { cursor:pointer } </style>
</head>
<body>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
<script type="text/ng-template" id="home.html">
<div class="page-header">
<h1>Hello World</h1>
</div>
</script>
</body>
</html>
I can't spot what seems to be going wrong in the code. I've also tried variations using /home.html in both the app config and html to no avail. I could use some insight on how I missed up the configuration/inline template.
If this is exactly your code you have a missing " in id of template. See below for correction
<script type="text/ng-template" id="home.html">
Your code is working fine for me. To further test it I added the following to the html:
<a ui-sref='home'>Home</a>
<a ui-sref='about'>About</a>
....
<script type="text/ng-template" id="about.html">
<div class="page-header">
<h1>About</h1>
</div>
</script>
I then added the following route to the javascript:
.state('about', {
url: '/about',
templateUrl: 'about.html',
controller: 'MainCtrl'
});
This adds links to the top left allowing you to switch views. You can see the working code at http://codepen.io/amartin007/pen/rLOvqa
I am developing a CRUD interface for a Rest service. Currently, I could manage to get the list of teams in the system.
What I like to do is to show details for the when I click the show link. Currently clicking on the link calls a function (not yet implemented) that is supposed to load the details part into the ng-view. The function should pass a parameter to the ViewTeamController which will subsequently invoke the Rest service and give the result to a $scope variable.
I am not sure about how to call the ViewTeamController possibly using a URL encoded parameter from the showTeam() function. And I would also like to know how to read the URL-encoded parameter inside the ViewTeamController.
Thanks in advance.
<!doctype html>
<html>
<head>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular-route.min.js"></script>
<script>
var teamApp = angular.module("teamApp", ['ngRoute']);
teamApp.controller('teamController', function($scope, $http) {
$http
.get('/teams')
.success(function(response) {
$scope.teams = response;
}
);
});
mainApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/addTeam', {
templateUrl: 'addTeam.htm',
controller: 'AddTeamController'
}).
when('/viewTeam', {
templateUrl: 'viewTeam.htm',
controller: 'ViewTeamController'
}).
otherwise({
redirectTo: '/addTeam'
});
}]);
mainApp.controller('AddTeamController', function($scope) {
});
mainApp.controller('ViewTeamController', function($scope) {
});
</script>
</head>
<body>
<div ng-app = "teamApp" ng-controller="teamController">
<a ng-click="newTeam()">new</a>
<div ng-repeat="team in teams" >
Name: {{team.name}}
<br />
Description: {{team.description}}
<br />
<a ng-click="showTeam(team.id)">show</a>
</div>
<div ng-view></div>
<script type = "text/ng-template" id = "addTeam.htm">
<h2> Add Team </h2>
To be implemented later.
</script>
<script type = "text/ng-template" id = "viewTeam.htm">
Name: {{team.name}}
Description: {{team.description}}
</script>
</div>
</body>
</html>
Your controller functions can get access to route parameters via the AngularJS $routeParams service like this:
mainApp.controller('ViewTeamController', function($scope, $routeParams) {
$scope.param = $routeParams.param; // will hold your encoded params
});
Considering you are passing the parameters as something like this in your URL,
/viewTeam/23535t4645645g4t4
Now your $scope.param will hold 23535t4645645g4t4
For example I have this input button:
<input type="button" class="blue-button pull-right" value="{{gb.gebruikerToevoegenText}} toevoegen" ng-click="gebruikers.addGebruiker()"/>
In the controller I am trying to achieve this through this logic:
vm.gebruikerToevoegenText = $location.path() == '/gebruikers' ? "Super User" : "Gebruiker";
But this guides me to same url for both views i.e. /gebruikers
I want its value to be different when the URL is /gebruikers/:id?/:naam?', below is the route definition:
$routeProvider.when('/gebruikers/:id?/:naam?', {
templateUrl: 'gebruikers.html',
controller: 'gebruikersController as gebruikers',
resolve: {
authentication: ['fwgAuthService', function (fwgAuthService) {
return fwgAuthService.login();
}]
}
});
$routeProvider.when('/gebruiker/:licentieHouderId/:id?', {
templateUrl: 'gebruiker.html',
controller: 'gebruikerController as vm',
resolve: {
authentication: ['fwgAuthService', function (fwgAuthService) {
return fwgAuthService.login();
}]
}
});
I want to change user rights as well on this URL , but only if I know how to manipulate the view based on URL, I do not want to change the template, other wise it is going to be lots of copy and paste.
You'll have to change the template anyways. Please don't pollute the rootScope for this; you can use ng-if or ng-show/hide (as already suggested). Just add an isAuthorized() function to your controller and set a flag if the url matches a certain pattern. Moreover I would alter the controllerAs name to the same name for both path in order to make templating easier.
I checked the url by using the following function in the controller thanks for helping out:
vm.gebruikerToevoegenText = $routeParams.id ? "Super User" : "Gebruiker";
Index.html
<!doctype html>
<html ng-app="routerApp">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<script>
var routerApp = angular.module('routerApp', ['ui.router', 'ngRoute']);
routerApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/gebruikers/:id?/:naam?', {
templateUrl: 'gebruiker.html',
controller: 'gebruikersController'
}).
when('/gebruiker/:licentieHouderId/:id?', {
templateUrl: 'gebruiker.html',
controller: 'gebruikerController'
}).
otherwise({
redirectTo: '/gebruikers/:id?/:naam?'
});
}]);
routerApp.controller('gebruikersController', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.toevoegen = "Pratapsss";
}]);
routerApp.controller('gebruikerController', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.toevoegen = "Pratap";
}]);
</script>
</head>
<body>
<div ng-view></div>
</body>
</html>
gebruiker.html
<div>
<input type="button" class="blue-button pull-right" ng-value="toevoegen" ng-click="gebruikers.addGebruiker()"/>
</div>
In my project, I do an AJAX request using AngularJS who call another page that includes Angular directives (I want to make another AJAX call inside) but no interaction in loaded page.
I think new DOM isn't functionnal.. I'm trying the pseudo-code $apply unsuccessed.
Main.html :
<!DOCTYPE html>
<html data-ng-app="App">
<head></head>
<body >
<div data-ng-controller="editeurMenuMobile">
<ul>
<li data-ng-click="callMenu('FirstAjax.html')" > <!-- Work ! -->
<a href="">
<span>Modèles</span>
</a>
</li>
<li data-ng-click="callMenu('FirstAjax.html')"> <!-- Work ! -->
<a href="">
<span>Designs</span>
</a>
</li>
</ul>
<div data-ng-bind-html="data">
<!-- AJAX content -->
</div>
</div>
<!-- Javascript scripts -->
</body>
</html>
FirstAjax.html :
<div data-ng-controller="editeurActionAjax">
<div>
<button data-ng-click="callAction('SecondAjax.html')"> <!-- Doesn't work -->
Go
</button>
</div>
</div>
And my JS :
var App = angular.module('App', []);
App.controller('editeurMenuAjax', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
$scope.callMenu = function(element) {
$http({method: 'GET', url: element}).
success(function(data) {
$scope.data = $sce.trustAsHtml(data);
}).
error(function() {
$scope.showAjaxError = true;
});
};
}
]);
App.controller('editeurActionAjax', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
$scope.callAction = function(element) {
$http({method: 'GET', url: element}).
success(function(data) {
$scope.data = $sce.trustAsHtml(data);
}).
error(function() {
});
};
}
]);
Thank you for your help
From my point of view could the problem be because of the $scope?
your 2nd Controller don't have access to the same data variable.
Try to change the code to use $rootScope in both controllers instead of $scope, and see if it fix the problem.
Or
On your FirstAjax.html insert this:
<div data-ng-bind-html="data">
<!-- AJAX content -->
</div>
This should make a second data variable inside Scope of Controller 2, so that it can place the content.
I resolve my problem with this response.
My new JS :
App.directive('bindHtmlUnsafe', function( $compile ) {
return function( $scope, $element, $attrs ) {
var compile = function( newHTML ) { // Create re-useable compile function
newHTML = $compile(newHTML)($scope); // Compile html
$element.html('').append(newHTML); // Clear and append it
};
var htmlName = $attrs.bindHtmlUnsafe; // Get the name of the variable
// Where the HTML is stored
$scope.$watch(htmlName, function( newHTML ) { // Watch for changes to
// the HTML
if(!newHTML) return;
compile(newHTML); // Compile it
});
};
});
var App = angular.module('App', []);
App.controller('editeurMenuAjax', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
$scope.callMenu = function(element) {
$http({method: 'GET', url: element}).
success(function(data) {
$scope.data = $sce.trustAsHtml(data);
}).
error(function() {
$scope.showAjaxError = true;
});
};
}
]);
App.controller('editeurActionAjax', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
$scope.callAction = function(element) {
$http({method: 'GET', url: element}).
success(function(data) {
$scope.data = $sce.trustAsHtml(data);
}).
error(function() {
});
};
}
]);
And new Main.html :
<!DOCTYPE html>
<html data-ng-app="App">
<head></head>
<body >
<div data-ng-controller="editeurMenuMobile">
<ul>
<li data-ng-click="callMenu('FirstAjax.html')" > <!-- Work ! -->
<a href="">
<span>Modèles</span>
</a>
</li>
<li data-ng-click="callMenu('FirstAjax.html')"> <!-- Work ! -->
<a href="">
<span>Designs</span>
</a>
</li>
</ul>
<div data-bind-html-unsafe="data">
<!-- AJAX content -->
</div>
</div>
<!-- Javascript scripts -->
</body>
</html>
And FirstAjax.html :
<div data-bind-html-unsafe='dataAction' >
<div class="addRubrique">
<button data-ng-click="callAction('SecondAjax.html')">
Ajouter
</button>
</div>
</div>
BindHtmlUnsafe the directive re-compile the new DOM to Angular knows the DOM loaded AJAX
I want to use a controller on 2 seperated HTML elements, and use the $rootScope to keep the 2 lists in sync when one is edited:
HTML
<ul class="nav" ng-controller="Menu">
<li ng-repeat="item in menu">
{{item.title}}
</li>
</ul>
<div ng-controller="Menu">
<input type="text" id="newItem" value="" />
<input type="submit" ng-click="addItem()" />
<ul class="nav" ng-controller="Menu">
<li ng-repeat="item in menu">
{{item.title}}
</li>
</ul>
</div>
JS
angular.module('menuApp', ['menuServices']).
run(function($rootScope){
$rootScope.menu = [];
});
angular.module('menuServices', ['ngResource']).
factory('MenuData', function ($resource) {
return $resource(
'/tool/menu.cfc',
{
returnFormat: 'json'
},
{
getMenu: {
method: 'GET',
params: {method: 'getMenu'}
},
addItem: {
method: 'GET',
params: {method: 'addItem'}
}
}
);
});
function Menu($scope, MenuData) {
// attempt to add new item
$scope.addNewItem = function(){
var thisItem = $('#newItem').val();
MenuData.addItem({item: thisItem},function(data){
$scope.updateMenu();
});
}
$scope.updateMenu = function() {
MenuData.getMenu({},function(data){
$scope.menu = data.MENU;
});
}
// get menu data
$scope.updateMenu();
}
When the page loads, both the UL and the DIV display the correct contents from the database, but when i use the addNewItem() method only the DIV gets updated.
Is there a better way to structure my logic, or can I do something to make sure the $scope.menu in the UL gets updated at the same time?
Here's an example of something similar: http://plnkr.co/edit/2a55gq
I would suggest to use a service that holds the menu and its methods. The service will update the menu which is referenced by the controller(s).
See a working plunker here: http://plnkr.co/edit/Bzjruq
This is the sample JavaScript code:
angular
.module( 'sampleApp', [] )
.service( 'MenuService', [ '$rootScope', function( $rootScope ) {
return {
menu: [ 'item 1' ],
add: function( item ) {
this.menu.push( item );
}
};
}])
.controller( 'ControllerA', [ 'MenuService', '$scope', function( MenuService, $scope ) {
$scope.menu = MenuService.menu;
$scope.addItem = function() {
MenuService.add( $scope.newItem );
};
}]);
And the sample Html page:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="sampleApp">
<div ng-controller="ControllerA">
<ul>
<li ng-repeat="item in menu">{{item}}</li>
</ul>
<input type="text" ng-model="newItem" /><input type="submit" ng-click="addItem()" />
</div>
<div ng-controller="ControllerA">
<ul>
<li ng-repeat="item in menu">{{item}}</li>
</ul>
</div>
</body>
</html>
Edit:
Here is the updated version plunker. it works in two controller.
Main idea is using service and broadcast to sync the data with the directive.
app.service('syncSRV', function ($rootScope) {
"use strict";
this.sync = function (data) {
this.syncData = data;
$rootScope.$broadcast('updated');
};
});
app.controller('MainCtrl1', ['$scope', function ($scope) {
}])
.controller('MainCtrl2', ['$scope', function ($scope) {
}]);
app.directive('sync',function (syncSRV) {
"use strict";
return {
template: '<div><input ng-model="syncdata" type="text" /></div> ',
controller: function ($scope, $element, $attrs) {
$scope.$watch('syncdata', function (newVal, oldVal, $scope) {
syncSRV.sync(newVal);
}, true);
}
};
}).directive('dataview', function (syncSRV) {
"use strict";
return {
template: '<div>Sync data : {{data}}</div> ',
controller: function ($scope, $element, $attrs) {
$scope.$on('updated', function () {
$scope.data = syncSRV.syncData;
});
}
};
});
<div ng-controller="MainCtrl1">
<fieldset>
<legend> Controller 1</legend>
<div dataview></div>
<div sync></div>
</fieldset>
</div>
<div ng-controller="MainCtrl2">
<fieldset>
<legend> Controller 2</legend>
<div dataview></div>
<div sync></div>
</fieldset>
</div>
Here is what I would do for this case.
I will create a directive for
<ul class="nav" ng-controller="Menu">
<li ng-repeat="item in menu">
{{item.title}}
</li>
</ul>
so once item is updated, it will be updated in both directive.
small example
I just want to update and simplify the selected answer. It seems you can reduce this by deleting this line:
$rootScope.$broadcast( 'MenuService.update', this.menu );
and this chunk:
$scope.$on( 'MenuService.update', function( event, menu ) {
$scope.menu = menu;
});
The reason being, we are already using a Service, and that basically binds the two identical controllers, so no need to use $rootScope.$broadcast and add an observable.
Working plunk here:
http://plnkr.co/edit/1efEwU?p=preview
You only need to link the service, when I refactor the code I was able to reduce it to 13 lines instead of 22.