How to "bind" the HTML representation to a controller - angularjs

I'm reading through some docs and books about Angular, but I don't really find an angular way of the following problem:
If I have a controller (let's say CardController), and another controller which handles the creation of multiple instances of the CardController. How should I implement the HTML-stuff? I want to be able to instantiate a Card, which has a specific HTML-code (like the one below) and is connected to the CardController.
I don't think that I should pollute the CardController to setup the HTML stuff with ugly .append-stuff. Or is this the way? Should I write an extra service for the HTML representation like CardView or create an extra directive?
If you look at this example, I want to be able to click on "Add another card" and see another instance of a card added below (so basically the ability to have multiple items):
<!DOCTYPE html>
<html ng-app="theApp">
<head>
<script data-require="angular.js#1.4.6" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
<div ng-controller="MainController">
<button ng-click="add()">Add another card</button>
</div>
<div id="content">
<div ng-controller="CardController">
<h1>{{ title }}</h1>
<p>{{ message }}</p>
</div>
</div>
<script>
(function() {
var app = angular.module("theApp", []);
app.controller('MainController', function($scope) {
$scope.add = function() {
// Setup HTML for TheController:
// add another DIV/H1/P-etc. to #content,
// just like the one at the beginning.
console.log("Add another card");
};
});
app.controller('CardController', function($scope) {
$scope.title = "A Title";
$scope.message = "Some message";
});
}());
</script>
</body>
</html>

Try this code from my snippet:
(function() {
var app = angular.module("theApp", []);
app.controller('MainController', function($scope) {
var iter = 1;
$scope.cards = [{
id: 1
}];
$scope.add = function() {
$scope.cards.push({
id: ++iter
});
// Setup HTML for TheController:
// add another DIV/H1/P-etc. to #content,
// just like the one at the beginning.
console.log("Add another card");
};
});
app.controller('CardController', function($scope) {
$scope.title = "A Title";
$scope.message = "Some message";
});
}());
<!DOCTYPE html>
<html ng-app="theApp">
<head>
<script data-require="angular.js#1.4.6" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body ng-controller="MainController">
<div>
<button ng-click="add()">Add another card</button>
</div>
<div id="content">
<div ng-repeat="card in cards" ng-controller="CardController">
<h1>{{ title }}</h1>
<p>{{ message }}</p>
</div>
</div>
</body>
</html>

There is few options. For example you can use angular directives (for me this is the most elegant solution) and create HTML structure like this:
<div ng-controller="MainController">
<button ng-click="add()">Add another card</button>
<div id="content">
<your-card-directive ng-repeat="card in cards" card-data="card"></your-card-directive>
</div>
</div>
or use ng-include to load HTML from your HTML files:
<div ng-controller="MainController">
<button ng-click="add()">Add another card</button>
<div ng-repeat="card in cards" ng-controller="CardController as CardCtrl" ng-include="'../../your-card-template.html'"></div>
</div>
or just use inline HTML:
<div ng-controller="MainController">
<button ng-click="add()">Add another card</button>
<div ng-repeat="card in cards" ng-controller="CardController">
<h1>{{ title }}</h1>
<p>{{ message }}</p>
</div>
</div>

one approach
<div ng-repeat="test in tests>{{test}}</div>
$scope.tests = ["Test Message","Test Message 2"];
$scope.tests.push("new msg");
this vl automatically create a div and ur list grows
or
http://blog.sodhanalibrary.com/2014/08/append-or-prepend-html-to-div-using.html#.Vhz-NxOqqko

Related

AngularJS Controller is not binding with HTML

Please find my my controller javascript file below -
angular.module('myApp', []);
angular.module('myApp').factory('myFactory', function () {
var myFactory = {};
myFactory.list = [];
myFactory.add = function (message) {
myFactory.list.push({ id: myFactory.list.length, text: message });
//return myFactory;
};
return myFactory;
});
angular.module('myApp').controller('Controller1', function (myFactory) {
var myVar = this;
myVar.myList = myFactory.List;
});
angular.module('myApp').controller('Controller2', function (myFactory) {
var myVar = this;
myVar.newMessage = 'Hello World!';
myVar.addMessage = function (message) {
myFactory.add(message);
myVar.newMessage = '';
};
});
And also my HTML file below -
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body ng-app="myApp">
<div>
<h1>Services</h1>
<div' ng-controller="Controller1">
<p ng-repeat="m in myList">{{ m.id }}: {{ m.text }}</p>
</div'>
</div>
<div ng-controller="Controller2 as post">
<form ng-submit="post.addMessage(post.newMessage)">
<input type="text" ng-model="post.newMessage">
<button type="submit"
ng-click="post.addMessage(post.newMessage)">
Add Message
</button>
</form>
</div>
</body>
</html>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.js"></script>
I can't see the data returning by the 'Controller1'
When I run the code I can't see the result which is coming from Controller1, which means the list is not binding with the ng-controller in .html page
Please tell me where I am wrong.
You are not referencing your list properly:
<p ng-repeat="m in myList">{{ m.id }}: {{ m.text }}</p>
If you are going to use myVar to store your list, you should use Controller as syntax so that your template has a reference to the variable:
<div ng-controller="Controller1 as myVar">
<p ng-repeat="m in myVar.myList">{{ m.id }}: {{ m.text }}</p>
</div>

Passing Data between state Providers in angular

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.

one controller two view

I have a view where the user gives an input and display it in another view.
view 1:
<ion-content ng-controller="controller">
<input type="text" ng-model="name">
<button ng-click="save()">Save</button>
Controller:
$scope.save = function () {
$scope.displayName = $scope.name;
$state.go('app.viewTwo');
}
View 2:
<ion-content ng-controller="controller">
{{displayName}}
</ion-content>
Its known, that whenever a view is loaded the controller is initialized fresh every time. So how to display the value from the first view, in another view.
You need to use a service or factory to use the variable across the controllers.
DEMO:
var app = angular.module("clientApp", [])
app.controller("TestCtrl",
function($scope,names) {
$scope.names =[];
$scope.save= function(){
names.add($scope.name);
}
$scope.getnames = function(){
$scope.names = names.get();
}
}
);
app.factory('names', function(){
var names = {};
names.list = [];
names.add = function(message){
names.list.push({message});
};
names.get = function(){
return names.list;
};
return names;
});
<!doctype html>
<html >
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="clientApp">
<div ng-controller="TestCtrl">
<input type="text" ng-model="name">
<button ng-click="save()" > save</button>
</div>
<div ng-init="getnames()" ng-controller="TestCtrl">
<div ng-repeat="name in names">
{{name}}
</div>
</div>
</body>
</html>
You can also use $rootScope , but it is not a recommended way.

Angular, data in one controller filter to this data in other

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>

AngularJS - ngClick not working on dynamically added html

I have a simple app in which i have a single input element with a mylist model.
If mylist=1 i ng-include first.html and if mylist=2 i ng-include second.html. So far so good.
My problem is that in each html template i have a button that when clicked i want to change the value of mylist so i can navigate to the other and in order to achieve this i do:
<button ng-click="mylist=x" >switch to x</button>
but ng-click doesn't work. Why?
Here is my code:
scripts.js
var myApp = angular.module('myApp', []);
myApp.controller('MainController', function ($scope) {
$scope.mylist = 1;
});
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://code.angularjs.org/1.2.16/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<input type="number" ng-model="mylist" />{{mylist}}
<br/>
<div ng-switch on="mylist">
<div ng-switch-when=1>
<ng-include src="'first.html'"></ng-include>
</div>
<div ng-switch-when=2>
<ng-include src="'second.html'"></ng-include>
</div>
</div>
</body>
</html>
first.html
<p>first</p>
<button ng-click="mylist=2" >switch to 2</button>
second.html
<p>second</p>
<button ng-click="mylist=1">switch to 1</button>
Also here is the Plunker http://plnkr.co/edit/bVATLV66kN21LC8EPeoW
ng-include creates a child scope. So you should bind to an object property instead of a primitive.
$scope.my = {
list: 1
};
http://plnkr.co/edit/SbeGch5MJdux33HgYsEJ?p=preview

Resources