Can an Angular JS template contain a controller? - angularjs

Here's my route...
angular.module('ng').
config(function ($routeProvider) {
$routeProvider.
when('/User_View', { templateUrl: '/rest/tbot/run/User_View' });
});
In the template it has the following...
<div ng-controller="TMUser">
TMUser is defined in the template in a script block. But the code in the controller doesn't appear to run. Why is this?

The controller shouldn't be defined in the template file. I don't think Angular can know about it and load it that way. Define it in a code file that will be executed before the route change happens.
You can also specify the controller in the routeProvider configuration object, like:
when('/User_View', { templateUrl: '/rest/tbot/run/User_View', controller:'TMUser' });
This fiddle demonstrates a very simple example (source)

Above answer is correct.
But i achived the same thing using ng-include and ng-hide, what exactly ng-view and routing does.
I have created a partial page without controller and included that in parent page and made that partial page hidden after a button click i am just displaying the page.
Routing has there on benifit. you can pass the paramter and change the view accordingly ang browser history.
here is my page conatins below code inside a child controller.
<span ng-include="'/PartialPages/ChangeDetails.htm'"></span>
which refers my parital page
<div id="ChangeInfo" ng-show="datashow">
<table width="100%">
<thead>
<tr>
<th>File Name</th>
<th>File Create Date</th>
<th>File Modified Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="file in FilesDetails" ng-class="{TableStrip : ($index % 2)}">
<td>{{file.FileName}}</td>
<td>{{file.CreateDate}}</td>
<td>{{file.ModifiedDate}}</td>
</tr>
</tbody>
</table>
<hr />
</div>
and the controller code
var deploymentVerifierModule = angular.module("DeploymentVerifierApp", ['DeploymentServiceModule']);
deploymentVerifierModule.controller("DeploymentVerifierCntrl", function ($scope, DeploymentService) {
$scope.datashow = false;
$scope.PleaseWait = false;
$scope.VerifyChange = function () {
//Get the Change ticket number from textbox
$scope.PleaseWait = true;
var changeticketnum = document.getElementById("ChangeNumber").value;
DeploymentService.GetChangeDetails(changeticketnum).then(function (data) {
$scope.FilesDetails = angular.fromJson(data);
$scope.PleaseWait = false;
$scope.datashow = true;
}, function (error) { });
};
});
still i did not get some of your point why do you want controller to be in template. and templateurl property contains the extenstion of page also.

Related

angularjs link between routes

I have set up a route as follows in my AngularJS app.
audit.config(["$routeProvider",function($routeProvider){
$routeProvider
.when('/AuditData/:auditCode', {
templateUrl: 'templ/AuditData.html',
controller: 'AuditDataController'
})
.when('/', {
templateUrl: 'templ/AuditSelect.html',
controller: 'AuditSelectController'
})
.when('/AuditSetup', {
templateUrl: 'templ/AuditSetup.html',
controller: 'AuditSetupController'
}}]);
The routing works as expected. The user is shown a list of audit codes in AuditSelect that are loaded from a REST service. Each item in the list is to be a link to the data associated with that code, i.e.: #/AuditData/:auditCode, <a href="#/AuditData/code123">.
(templ/AuditSelect.html):
<div>
<table>
<tr>
<th>Audit Code</th>
<th>Description</th>
</tr>
<tr ng-repeat="auditCode in auditCodes">
<td> {{auditCode.auditCode}}</td>
<td>{{auditCode.description}}</td>
</tr>
</table>
</div>
My problem is that when the users clicks on the link, they are taken back to '/' and not '/AuditData/:auditCode'.
Update:
I found what was wrong :-) I was missing a bang in the href in my template. I've also switched to using ng-href (which didn't work without the bang either, but does with it)
<td><a ng-href="#!/AuditData/{{auditCode.auditCode}}">{{auditCode.auditCode}}</a></td>

Angular JavaScript Update $scope variable onClick

I'm trying to update a $scope variable onClick that populates a table from a local JSON file. So far my code is
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $http) {
$scope.update = function () {
// Load JSON data to $scope
$http({
method: 'get',
url: '/JSON/Info.json'
}).then(function (response) {
console.log(response, 'res');
$scope.friendz = response.data[1];
},function (error){
console.log(error, 'can not get data.');
});
}
});
<div ng-controller="myCtrl" class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<button class="dropdown-item" ng-click="update()">Action</button>
</div>
<div ng-controller="myCtrl">
<table border="1">
<tr>
<th>Name</th>
<th>Fax</th>
<th>Phone</th>
<th>Address</th>
<th>Attention</th>
<th>Submission</th>
</tr>
<tr>
<td ng-bind="friendz.Payee.Name"></td>
<td ng-bind="friendz.Payee.Fax"></td>
<td ng-bind="friendz.Payee.Phone"></td>
<td ng-bind="friendz.Payee.Address"></td>
<td ng-bind="friendz.Payee.Attention"></td>
<td ng-bind="friendz.Payee.SubmissionDate"></td>
</tr>
</table>
</div>
When I click my update button in the dropdown menu, I see the response is logged in the console, but the table fails to update onClick. Is there a function that I need to call to update the page in an asynchronous fashion when I click my button? When I use the http get function outside of my scope.update function, it works fine on page load.
You're creating two separate instances of your controller, since you have ng-controller="myCtrl" twice in the template.
So he controller handling the click is not the same one that holds the data displayed by the table. And their scope are not the same either: each controller instance has its own scope.

Using AngularJS, how can I use a public variable in the DOM?

Using AngularJS I am sending a user to a page that has a query string based on employees they selected on a previous page. I am logging this variable, users, correctly but I can't use it with an ng-if in the DOM. I want to use ng-if when user.ID from the DOM equals user from the JS.
The HTML is:
<div ng-app="myApp">
<div ng-controller="MainCtrl">
<div class="ProfileSheet" ng-repeat="user in users" ng-if="user.ID == user">
<h3 class="heading">User Profile</h3>
<table id="Profile">
<tr>
<th>User</th>
<td>{{user.Title}}</td>
</tr>
<tr>
<th> User Admin ID</th>
<td>{{user.ID}}</td>
</tr>
</table>
<br>
</div>
</div>
The JS is:
var app = angular.module('myApp', ['ngSanitize']);
app.controller('MainCtrl', function($scope, $http, $q){
var getQueryString = function (field, url){
var href = url ? url : window.location.href;
var reg = new RegExp('[?&]' + field + '=([^&#]*)', 'i');
var string = reg.exec(href);
return string ? string[1] : null;
}
var users = getQueryString('users', window.location.href)
$(document).ready(function() {
console.log(users);
});
How can I make this work?
Bonus: How can I make theng-repeat work if multiple users were selected. For example: if the query string returns users as 19, 21, and 25 the ng-repeat currently looks for a user ID of 19,21,25. Not three separate items.
Set $scope.users instead of var users. The template code uses scope variables: what you call as var_name in your template is actually $scope.var_name in the controller.
I was able to do this with $scope.selectedusers and ng-if="user.ID == selectedusers. Using $scope.users resulted in errors probably from using ng-repeat = "user in users".

Controller is not a function, got undefined

I'm trying to create a directive on a controller. The directive will create a table of items returned from djangorestframework.
controller.js:
var expensesApp = angular.module('expensesApp', []);
expensesApp.controller('ShoppingListController', ['$scope', '$http',
function($scope, $http){
$http(
{
method: 'GET',
url: '/items/?format=json'
})
.success(function(data, status, headers, config) {
$scope.items = data;
})
.error(function(data, status, headers, config) {
});
}]);
directive.js
angular.module('expensesApp', [])
.directive('shoppingList', function () {
return {
restrict: 'A',
templateUrl: 'http://localhost:8000/static/angular/partials/shopping-list.html',
controller: 'ShoppingListController'
};
})
The partial being pulled in by the directive:
shopping-list.html
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>ID</th>
<th>NAME</th>
<th>SHOP</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items">
<td>[[ item.id ]]</td>
<td>[[ item.name ]]</td>
<td>[[ item.shop ]]</td>
</tr>
</tbody>
</table>
and the main html page where I define the app and the controller.
items.html
...
<div class="container" ng-app="expensesApp">
<div class="row">
<div class="col-md-6" ng-controller="ShoppingListController">
<div shopping-list></div>
</div>
</div>
</div>
...
The headers of the table in the partial are being pulled into the page, but it's not executing the $http and fetching the items that should make up the content of the table. I get ShoppingListController not a function, got undefined
Everything works if I don't split the table out into a directive. All items are returned and I don't see the error in the console.
Anyone have any idea what I'm doing wrong?
You are redefining module when you create a directive. It should be:
angular.module('expensesApp')
.directive('shoppingList', function () {
return {
restrict: 'A',
templateUrl: 'http://localhost:8000/static/angular/partials/shopping-list.html',
controller: 'ShoppingListController'
};
});
If you pass an array as the second argument to module method angular.module('expensesApp', []), Angular creates a new module without ShoppingListController controller in it. You should use getter syntax angular.module('expensesApp') to retrieve previously created module.

directive only works inside another directive

i made a directive for filtering data. It uses scope: true and no transclusion. Somehow it only works inside an ng-switch. Maybe also other directives but i havent tried.
My html looks like this:
<my-filter source="{{foodArray}}" filter="reaction,category"> // source and filter are properties on the directive scope
<div>
<div class="span3">
<table class="table table-bordered">
<tr data-ng-repeat="item in filters.reaction"> // filters property of directive scope
<td><input type="checkbox" data-ng-model="item.isChecked" data-ng-change="filterCtrl.filterList()"></td>
<td>{{ item.value }}</td>
</tr>
</table>
</div>
</div>
<table>
<tbody>
<tr data-ng-repeat="food in filteredData"> // filteredData object on the directive scope
// interating through filteredData
</tr>
</tbody>
</table>
</my-filter>
here is my directive and its controller:
angular.module('myModule', [])
.directive('myFilter', function() {
return {
restrict: 'E',
scope: true,
controller: ["$scope", function ($scope) {
var filterCtrl = this;
$scope.filters = {};
filterCtrl.inputArray = [];
filterCtrl.filterList = function() {
/* some code where tmp array is created */
$scope.filteredData = tmp;
}
}],
controllerAs: 'filterCtrl',
link: function(scope, element, attrs, filterCtrl) {
filterCtrl.inputArray = angular.fromJson(attrs.source);
scope.filteredData = filterCtrl.inputArray;
// ...
}
}
});
FilteredData and filters are property of the directives scope. Now when i remove the ng switch around it the data is empty. Also the scope.source property can be an array or an object. When i remove the ng switch and give it an object as source it actually throws a syntax error: SyntaxError: Unexpected end of input
at Object.parse (native)
at Object.fromJson
Which it doesnt throw when i use an array.
Not sure what to make of this. If anybody had this problem before i would love to hear from you.

Resources