Im looking to pass data between 2 controllers in Angular, Below is code i started
There are 2 views one with input field and other with a link.
when i click on link in the second view i should be able to set a state and state data should be populated in input field in first field.
I tried several approaches but im missing something.
Can someone help me here
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello AngularJS</title>
<script data-require="angular.js#1.2.10" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.min.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(['$stateProvider','$stateProvider', '$urlRouterProvider', function ($stateProvider,$urlRouterProvider) {
var addBook = {
name: 'addBook',
url: '/addBook',
template: '<h2>Add A book</h2> Data from View <input type="text" ng-model={{input-text}}>' ,
data:""
},
viewBookv = {
name: 'viewBookv',
url: '/viewBook',
template: '<h2>View A book</h2><span class="glyphicon glyphicon-edit">Edit</span> ' ,
};
$stateProvider.state(addBook, "controller: editUserCtrl");
$stateProvider.state(viewBookv, "controller: editUserCtrl");
}])
myApp.controller('editUserCtrl', function($scope, $stateParams) {
$scope.paramOne = $stateParams.data;
$scope.edit = function () {
event.preventDefault();
$state.go("addBook");
}
})
myApp.controller('mainController',function($scope, $rootScope, $state,$window){
$scope.addBook=function(){
$state.go("addBook");
};
$scope.viewbookls= function(){
$state.go("viewBookv");
};
})
</script>
</head>
<body>
<div class="container">
<div class="col">
<div class="col-md-3" ng-controller="mainController">
<ul class="nav">
<li> View Book </li>
<li> Add Book </li>
</ul>
</div>
<div class="col-md-9">
<div ui-view></div>
</div>
</div>
</div>
</body>
</html>
Typically in angular the way to share state between controllers is using a service. So the way it's usually set up is to setup a service then import that service into the relevant controllers, and that data gets shared between them. I've modified your example above to follow this pattern(I'm not quite sure what you were trying to do)
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello AngularJS</title>
<script data-require="angular.js#1.2.10" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.min.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider,$urlRouterProvider) {
var addBook = {
name: 'addBook',
url: '/addBook',
template: '<h2>Add A book</h2> Data from View <button ng-click="updateBook()">Update</button> <input type="text" ng-model="inputText">' ,
controller: "addBookCtrl",
data:""
},
viewBookv = {
name: 'viewBooks',
url: '/viewBook',
template: '<h2>View A book</h2><div ng-repeat="book in bookList">{{book}}</div>',
controller: "viewBookCtrl",
};
$stateProvider.state('addBook', addBook);
$stateProvider.state('viewBooks', viewBookv);
}])
myApp.controller('addBookCtrl', function($scope, bookService) {
$scope.updateBook = function(){
console.log( $scope.inputText)
bookService.books.push($scope.inputText);
}
})
myApp.controller('viewBookCtrl', function($scope, bookService) {
$scope.bookList = bookService.books
})
myApp.factory('bookService', function() {
var bookService = {};
bookService.books = [];
return bookService;
});
myApp.controller('mainController',function($scope, $rootScope, $state,$window){
$scope.addBook=function(){
$state.go("addBook");
};
$scope.viewbookls= function(){
$state.go("viewBooks");
};
})
</script>
</head>
<body>
<div class="container">
<div class="col">
<div class="col-md-3" ng-controller="mainController">
<ul class="nav">
<li> View Book </li>
<li> Add Book </li>
</ul>
</div>
<div class="col-md-9">
<div ui-view></div>
</div>
</div>
</div>
</body>
</html>
What this example does, is in the text box for add book, you type in the name (then click update), this appends it to an array so every time you do it you'll get a new element on that array. From there head over to the view books page, and you'll see all the different things you typed in.
Related
I am trying to call one angular js function using controller. I am using code:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DevPortal</title>
<script src="js/angular.min.js"></script>
<script src="js/controllers/app.js"></script>
</head>
<body ng-app="devportal">
<div ng-include="'templates/login_menu.html'"></div>
</body>
</html>
app.js
var app = angular.module('devportal', []);
app.controller('AppController', function($scope, $http) {
return{
getuserloginmenu : function(){$http.get('/getuserloginmenu').then(function(response){$scope.loginmenu=response.data;})},
getuserloginmenu1 : function(){$http.get('/getuserloginmenu1').then(function(response){$scope.loginmenu1=response.data;})}
};
});
login_menu.html
<div ng-controller="AppController as ctrl">
<div on-init="ctrl.getuserloginmenu()">
<p ng-repeat="menu in loginmenu">{{menu}}</p>
</div>
</div>
My rest service is working properly and returns String array. I am not able to call/get the rest service data in html.
Your code seems legit, the only thing making noise (at least for me) is the on-init you added to call the function. I think that's the problem.
Try
<div ng-controller="AppController as ctrl">
<div ng-init="ctrl.getuserloginmenu()">
<p ng-repeat="menu in loginmenu">{{menu}}</p>
</div>
</div>
And maybe.. To keep it clean: Change the syntax of the controller (even if it works)
var app = angular.module('devportal', []);
app.controller('AppController', function($scope, $http) {
$scope.getuserloginmenu = function(){$http.get('/getuserloginmenu').then(function(response){$scope.loginmenu=response.data;})};
$scope.getuserloginmenu1 = function(){$http.get('/getuserloginmenu1').then(function(response){$scope.loginmenu1=response.data;})};
});
Edit:
That's a missuse of ng-init. I'll leave the documentation of Angular for that matter
https://www.w3schools.com/angular/ng_ng-init.asp
But shortly, you want $scope.loginmenu to populate. You don't need to wait until the div loads. You can populate $scope.loginmenu right away when the controller inits.
View
<div ng-controller="AppController as ctrl">
<div>
<p ng-repeat="menu in loginmenu">{{menu}}</p>
</div>
</div>
Controller
var app = angular.module('devportal', []);
app.controller('AppController', function($scope, $http) {
$scope.getuserloginmenu = function(){$http.get('/getuserloginmenu').then(function(response){$scope.loginmenu=response.data;})};
$scope.getuserloginmenu1 = function(){$http.get('/getuserloginmenu1').then(function(response){$scope.loginmenu1=response.data;})};
$scope.getuserloginmenu();
});
Im working in laravel and i start to implement angular to my frontend.
This is the route:
Route::get('test', 'WorkController#inicio');
My controller function:
public function inicio()
{
$works = new Work;
$works = Work::Paginate(10);
return view('test', compact('works'));
}
And the view where i what to display the database information.
<head>
<title>test</title>
<link href="/css/lib.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js">
</script>
</head>
<body>
<h1>test</h1>
<h2>test</h2>
<div ng-app="myApp" ng-controller="myController as controller">
<ul>
<li ng-repeat="datos in data">
<a class="floating-box">#{{datos.client}}</a>
</li>
</ul>
</div>
<hr/>
</body>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("myController", function($scope, $http) {
$scope.data = [];
$scope.buscador = '';
$http.get("<?=env('APP_URL')?>" + '/test').then(function(datos) {
console.log(datos.data.data);
$scope.data = datos.data.data;
console.log($scope.data);
})
});
</script>
But then i get this in console:
GET http://localhost/test net::ERR_CONNECTION_REFUSED.
and the information isnt in the view.
Now, I write an Angular1.5+ component in one folder.
The component in an independent folder.
My issue is how to use this component in different HTML. In other words, I want to find a method to import this component in more than two HTML files.
The cellComponent.js is like this:
function courseCellComponentFun() {
var ctrl = this;
}
angular.module(app_name).component('courseCell', {
templateUrl: '../cellComponent.html',
controller:courseCellComponentFun,
bindings:{
cellData:'='
}
})
The cellComponent.html is like this:
<div class="course_cell">
<div class="img_box">
<div ng-bind="$ctrl.cellData.name"></div>
</div>
</div>
The index.html like this:
<body ng-app="app" ng-controller="controller">
<ul>
<li ng-repeat="item in array1">
<course-cell cell-data="item"></course-cell>
</li>
</ul>
</body>
<script src="angular.js"></script>
<script>
var app = angular.module('app',[]);
app.controller('controller', function ($scope) {
$scope.array1 = [
{name:'cell1'},
{name:'cell2'},
{name:'cell3'},
]
});
</script>
How to import the component in the index.hmtl? My index.html does not work now. I can't see the text.
Well, If you're not using Typescript or Babel or the new ES6 standard for importing and exporting modules, I'm affraid you have to add the reference of your component.js file, as simple as <script src="cellComponent.js"></script>in the index.html
index.html
<html>
<head>
<script src="angular.js"></script>
<script src="cellComponent.js"></script>
<script src="appModule.js"></script>
</head>
<body ng-app="app" ng-controller="controller">
<ul>
<li ng-repeat="item in array1">
<course-cell cell-data="item"></course-cell>
</li>
</ul>
</body>
</html>
appModule.js
var app = angular.module('app',[]);
app.controller('controller', function ($scope) {
$scope.array1 = [
{name:'cell1'},
{name:'cell2'},
{name:'cell3'},
];
})
.component("courseCell", componentOpts); // componentOpts comes from the componentOpts.js script
cellComponent.html
<div class="course_cell">
<div class="img_box">
<div ng-bind="$ctrl.cellData.name"></div>
</div>
</div>
cellComponent.js
function courseCellComponent() {
var ctrl = this;
}
var componentOpts = {
templateUrl: './cellComponent.html',
controller: courseCellComponent,
controllerAs: "$ctrl",
bindings: {
cellData:'=',
}
};
See this plunkr
At start i want to say im new in angular. Lets say my page look like this:
index.html:
<body ng-app="application">
<div class="container">
<div class="row">
<div class="col-sm-3 sideBar" ng-controller="NavController">
<input ng-model"search">
</div>
<div class="col-sm-9 content" ng-controller="ContentController">
<div ng-repeat="meet in meets | filter:search">
{{ meet.someData }}
</div>
</div>
</div>
</div>
</body>
And how can i make that input in NavController could filter data from ContentController? I want to do this in two controllers.
I'm not sure why you want to do this in two controllers, but it will be considerably more difficult. The Search functionality acts on the data in the content controller. I am guessing that your layout is driving your controller design.
There are numerous posts here that discuss techniques for this. This one: Share data between AngularJS controllers is well-regarded.
Actually you can just do that in a single controller.
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.name = [{
"id":1
},{
"id":2
},{
"id":3
}]
});
<!DOCTYPE html>
<html ng-app="angularjs-starter">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//code.angularjs.org/1.1.1/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl"><input ng-model='find' />
<div ng-repeat="x in name | filter : find">
{{x.id}}
</div>
</body>
</html>
For understanding, i used numbers as data. :) Hope it helps you
You can have a parent controller over the other two controllers. If you use the controllerAs method you can have controllers inside each other, see Angular Style Guide for helpful information about controllers and controllerAs.
You could write it like that and bind the search model to the ParentController.
Edit: I added another solution that I think is better
var app = angular.module('app', []);
app.controller('ParentController', function() {
this.search = 'p'; //set default just for fun
});
app.controller('NavController', function() {
//nav stuff
});
app.controller('ContentController', function() {
this.meets = [{
data: 'hi'
}, {
data: 'potato'
}, {
data: 'help me'
}, {
data: 'pie'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<div class="container" ng-controller="ParentController as parentVm">
<div class="row">
<div class="col-sm-3 sideBar" ng-controller="NavController as navVm">
<input ng-model="parentVm.search">
</div>
<div class="col-sm-9 content" ng-controller="ContentController as contentVm">
<div ng-repeat="meet in contentVm.meets | filter:parentVm.search">
{{ meet.data }}
</div>
</div>
</div>
</div>
</body>
I stepped away from this for a bit and thought of another idea that doesn't involve using another controller. Here you are using a factory instead to communicate between the controllers. You have to share an object so that when you change the search.term in the input it will change for every reference.
var app = angular.module('app', []);
app.factory('Searcher', function() {
return {
search: {
term: 'p'
}
};
});
app.controller('NavController', function(Searcher) {
//nav stuff
this.search = Searcher.search;
});
app.controller('ContentController', function(Searcher) {
this.search = Searcher.search;
this.meets = [{
data: 'hi'
}, {
data: 'potato'
}, {
data: 'help me'
}, {
data: 'pie'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app">
<div class="container">
<div class="row">
<div class="col-sm-3 sideBar" ng-controller="NavController as navVm">
<input ng-model="navVm.search.term">
</div>
<div class="col-sm-9 content" ng-controller="ContentController as contentVm">
<div ng-repeat="meet in contentVm.meets | filter:contentVm.search.term">
{{ meet.data }}
</div>
</div>
</div>
</div>
</body>
I took a sample AngularJS app and began to change it to suit my needs. Now clicking to change the orderby causes the entire controller to be reloaded. Well that's where I'm initializing the default orderby. So what I get when I click a new orderby is a flash of the proper orderby then a quick return to the default. An alert showed me the controller is getting executed but I don't know why or how to fix it.
Plunker here
index.html
<!DOCTYPE html>
<html data-ng-app="promptsApp">
<head>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<link href="style.css" rel="stylesheet" />
</head>
<body>
<div ng-view></div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="app.js"></script>
<script src="controllers.js"></script>
<script src="promptsService.js"></script>
</body>
</html>
app.js
var app = angular.module('promptsApp', []);
app.config(function ($routeProvider) {
$routeProvider
.when('/prompts',
{
controller: 'PromptsController',
templateUrl: 'partial.html'
})
.otherwise({ redirectTo: '/prompts' });
});
controllers.js
app.controller('PromptsController', function ($scope, promptsService)
{
init();
function init()
{
$scope.prompts = promptsService.getPrompts();
$scope.orderby='TRANSFEREE';
$scope.reverse = false;
//alert('Hi');
}
$scope.setOrder = function (orderby) {
if (orderby === $scope.orderby)
{
$scope.reverse = !$scope.reverse;
}
$scope.orderby = orderby;
};
});
promptsService.js
app.service('promptsService', function ()
{
this.getPrompts = function (user)
{
var prompts = [
{
id: 1, NOTE: 'Call client about something', CALLBACK_DATE: '12-01-2013', TRANSFEREE: 'Tom Tuttle', REG_NUM: '123456'
},
{
id: 2, NOTE: 'Notify client of delay', CALLBACK_DATE: '12-10-2013', TRANSFEREE: 'Eddie Munster', REG_NUM: '101314'
},
{
id: 3, NOTE: 'Complete paperwork', CALLBACK_DATE: '12-12-2013', TRANSFEREE: 'Mary Tyler Moore', REG_NUM: '998877'
}
];
return prompts;
};
});
partial.html
<div class="prompts">
<div class="container">
<header>
<h3>Prompts</h3>
<ul class="nav nav-pills">
<li ng-class="{'active': orderby=='CALLBACK_DATE'}">Date</li>
<li ng-class="{'active': orderby=='TRANSFEREE'}">Transferee</li>
<li> (Currently: {{orderby}})</li>
</ul>
</header>
<div>
<div class="row cardContainer">
<div class="span3 card" data-ng-repeat="prompt in prompts | orderBy:orderby:reverse">
<div class="cardHeader">{{prompt.TRANSFEREE}}</div>
<div class="cardBody">{{prompt.NOTE}}
<br># {{prompt.REG_NUM}} {{prompt.CALLBACK_DATE}}
</div>
</div>
</div>
</div>
<br />
{{prompts.length}} prompts
</div>
</div>
See Plunker here
<li ng-class="{'active': orderby=='CALLBACK_DATE'}">
<a href="" ng-click="setOrder('CALLBACK_DATE')">\
CallBack Date
</a>
</li>
<li ng-class="{'active': orderby=='TRANSFEREE'}">
<a href="" ng-click="setOrder('TRANSFEREE')">
Transferee
</a>
</li>
<li>> Currently: {{orderby}}</li>
Remove the href="#" and replace it with href="" to get the desired result.
Having href="#" causes the route to change (and become the same as before) but triggers the initialization of the controller once more.