AngularJS, updating scope between controllers and html - angularjs

I have built a service that is keeping track of the id of a record within a telerik grid. On selecting a row in the grid the service successfully fires and updates the data. My problem is that the controller that handles my navigation doesn't see the change and I don't fully understand how to accomplish this as I am fairly new to angularjs and front end development.
app
.controller('FindCardCtrl', ['$scope', '$http', 'NavService', function($scope, $http, NavService) {
$http.get('../../sampleData/cardData.json').then(function(data) {
var cardObj = data.data.cards;
var grid = $("#grid").kendoGrid({
dataSource: {
data: cardObj.card,
},
columns: [{
hidden: true,
field: "id"
},
{
field: "card_number",
title: "Card Number"
},
{
field: "name_on_card",
title: "Name On Card"
},
{
field: "billing_zip_code",
title: "Billing Zip Code"
},
{
field: "balance",
title: "Balance"
}
],
noRecords: true,
editable: false,
sortable: true,
reorderable: true,
selectable: "row",
change: function(e) {
var selectedRows = this.select();
var selectedDataItems = [];
for (var i = 0; i < selectedRows.length; i++) {
var dataItem = this.dataItem(selectedRows[i]);
selectedDataItems.push(dataItem);
}
NavService.setCardId(selectedDataItems[0].id);
},
pageable: {
pageSize: 20,
previousNext: true,
input: true,
buttonCount: 5,
pageSizes: [20, 30, 40, "all"],
info: true,
messages: {
page: "Enter page"
}
},
filterable: {
mode: "menu",
ignoreCase: true,
operators: {
string: {
eq: "Equal to",
contains: "Contains",
startswith: "Begins with"
},
date: {
eq: "Equal to",
gt: "After",
lt: "Before",
eq: "Equals",
gte: "After or equal to",
lte: "Before or equal to"
}
}
}
});
});
}]);
'use strict';
app
.controller('NavCtrl', ['$scope', '$http', 'NavService', function($scope, $http, NavService) {
$scope.oneAtATime = false;
//$http.get('../../sampleData/cardData.json').then(function (data) {
//var card = getObjects(data, "id", NavService.cardData.cardId);
// });
$scope.$on('card-selected', function(event, NavService) {
console.log(NavService.cardData.cardId);
});
// console.log(NavService.cardData.cardId);
//$scope.cardId = NavService.cardData.cardId;
$scope.status = {
isFirstOpen: true
};
}]);
function getObjects(obj, key, val) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val));
} else if (i == key && obj[key] == val) {
objects.push(obj);
}
}
return objects;
}
'use strict';
/**
* #ngdoc overview
* #name backOfficeApp
* #description
* # backOfficeApp
*
* Main module of the application.
*/
/*jshint -W079 */
var app = angular
.module('backOfficeApp', [
'ngAnimate',
'ngCookies',
'ngResource',
'ngSanitize',
'ngTouch',
'ngMessages',
'picardy.fontawesome',
'ui.bootstrap',
'ui.router',
'ui.utils',
'angular-loading-bar',
'angular-momentjs',
'kendo.directives',
'FBAngular',
'lazyModel',
'angularBootstrapNavTree',
'angularFileUpload',
'oc.lazyLoad',
'ui.select',
'ui.tree',
'ui.calendar',
'pascalprecht.translate',
'ngMaterial',
'localytics.directives',
'ipsum',
'angular-intro',
'dragularModule'
])
.run(['$rootScope', '$state', '$stateParams', function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.$on('$stateChangeSuccess', function(event, toState) {
event.targetScope.$watch('$viewContentLoaded', function() {
angular.element('html, body, #content').animate({
scrollTop: 0
}, 200);
setTimeout(function() {
angular.element('#wrap').css('visibility', 'visible');
if (!angular.element('.dropdown').hasClass('open')) {
angular.element('.dropdown').find('>ul').slideUp();
}
}, 200);
});
$rootScope.containerClass = toState.containerClass;
});
}])
.config(['uiSelectConfig', function(uiSelectConfig) {
uiSelectConfig.theme = 'bootstrap';
}])
//angular-language
.config(['$translateProvider', function($translateProvider) {
$translateProvider.useStaticFilesLoader({
prefix: 'languages/',
suffix: '.json'
});
$translateProvider.useLocalStorage();
$translateProvider.preferredLanguage('en');
$translateProvider.useSanitizeValueStrategy(null);
}])
.config(['$provide', function($provide) {
$provide.factory('NavService', function($q) {
var dataHolder = {};
//It's important that you use an object or an array here a string or other
//primitive type can't be updated with angular.copy and changes to those
//primitives can't be watched.
dataHolder.cardData = {
"cardId": '0'
};
dataHolder.setCardId = function(id) {
var deferred = $q.defer();
var cardId = id;
angular.copy(cardId, dataHolder.cardData);
deferred.resolve(dataHolder.cardData);
return deferred.promise;
}
return dataHolder;
})
}])
<div id="sidebar-wrap" ng-controller="NavCtrl">
<uib-accordion close-others="oneAtTime" slimscroll="{height: '100%'}">
<div uib-accordion-group is-open="status.isFirstOpen" class="panel-default">
<ul id="navigation" nav-collapse ripple>
<li ui-sref-active="active">
<a ui-sref="client.dashboard">
<fa name="dashboard"></fa> <span>{{ 'Menu.DASHBOARD'| translate }}</span></a>
</li>
<li ui-sref-active="active" ng-class="{'open':$state.includes('client.order')}">
<a ui-sref="client.order">
<fa name="shopping-cart"></fa> <span>{{ 'Menu.ORDER_MANAGEMENT' | translate }}</span></a>
<ul>
<li ui-sref-active="active">
<a ui-sref="client.order_management.new">
<fa name="caret-right"></fa> {{ 'Menu.NEW_ORDER' | translate }}</a>
</li>
<li ui-sref-active="active">
<a ui-sref="client.order_management.history">
<fa name="caret-right"></fa> {{ 'Menu.HISTORY' | translate }}</a>
</li>
<li ui-sref-active="active">
<a ui-sref="client.order_management.cancel">
<fa name="caret-right"></fa> {{ 'Menu.CANCEL' | translate }}</a>
</li>
</ul>
</li>
<li ui-sref-active="active" ng-class="{'open':$state.includes('client.card')}">
<a ui-sref="client.card">
<fa name="credit-card"></fa> <span>{{ 'Menu.CARD_MANAGEMENT' | translate }}</span></a>
<ul>
<li ui-sref-active="active">
<a ui-sref="client.card_management.find">
<fa name="search"></fa> {{ 'Menu.FIND_CARD' | translate }}</a>
</li>
</ul>
<ul ng-if="cardId > 0">
<li ui-sref-active="active">
<a ui-sref="client.card_management.summary({cardId: cardId})">
<fa name="caret-right"></fa> {{ 'Menu.SUMMARY'| translate }} </a>
</li>
</ul>
</li>
</ul>
</div>
</uib-accordion>
</div>

You can use the event system in Angular to notify other controllers that they need to update their values:
app.service('MyService', function($rootScope) {
var MyService = this;
var item;
MyService.setItem = function(value) {
/*-- code to set item --*/
// notify other controllers
$rootScope.$broadcast('item-changed');
};
MyService.getItem = function() {
// api call to get item
// or get current item value from variable
};
});
app.controller('MyOtherController', function($scope, MyService) {
$scope.$on('item-changed', function() {
MyService.getItem().then(function(result) {
$scope.item = result;
});
});
});
In your NavCtrl, you are most of the way there, you just need to set the scope variable to the new cardId in your event listener:
.controller('NavCtrl', [
'$scope', '$http', 'NavService',
function($scope, $http, NavService) {
//...
$scope.$on('card-selected', function(event, NavService) {
console.log(NavService.cardData.cardId);
$scope.cardId = NavService.cardData.cardId;
});
//...
}]);
You can't inject $scope into a service, but you can inject $rootScope. Broadcasting an event on $rootScope with send it to all scopes. Any scope that is listening for it will be able to respond to it.

Related

AngularJS - Watch filtered list for changes

Within angular I have a filtered list of people that takes the filter criteria from a predicate function. I want to watch a variable of the filtered list (called filteredPeople) every time the filtered list changes. But I am unable to see when that variable changes.
My code is below:
HTML:
<ul>
<li ng-repeat="person in ($ctrl.filteredPeople = ($ctrl.people | filter: $ctrl.filter))">
...
</li>
</ul>
JS:
controller: ['$scope',
function ($scope) {
var $ctrl = this;
$ctrl.people = {...}
$ctrl.filteredPeople = [];
$scope.$watch($ctrl.filteredPeople, function () {
console.log("called"); //not being called
});
$ctrl.filter = function (p) {
//custom filter function for each item in the array of people
}
}]
I can answer any questions of provide more code if needed
angular.module('app', []).controller('ctrl', function($scope) {
var vm = this;
vm.items = [
{ name: 'Sam' },
{ name: 'Max' },
{ name: 'Tom' },
{ name: 'Henry' },
{ name: 'Jack' },
{ name: 'Kate' }
]
var counter = 1;
$scope.$watchCollection('vm.filtered', function(){
console.log('Changed' + counter++);
})
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<div ng-app='app' ng-controller='ctrl as vm'>
<input type='text' ng-model='vm.filter' />
<ul>
<li ng-repeat='item in vm.filtered = (vm.items | filter : vm.filter)'>{{item}}</li>
</ul>
</div>

angularjs show/hide tabs

Here i am displaying tabs from array using angularjs and bootstrap.
What i want is when i click on particular tab it should display content of that tab only.
i.e(When i click on dynamic-2 i want to display content of dynamic 2 and hide the content of dynamic-1 and dynamic-3 tab)
Right now i am getting content of all tabs on clicking.
js file
var items=[
{
Name:"tab1",
id:1,
content:"FirstTab",
title:"Dynamic-1",
templateUrl:"first.html"
},
{
Name:"tab2",
id:2,
content:"SecondTab",
title:"Dynamic-2",
templateUrl:"second.html"
},
{
Name:"tab3",
id:3,
content:"ThirdTab",
title:"Dynamic-3",
templateUrl:"third.html"
}
];
}]);
html file
<ul class="nav nav-tabs">
<li ng-repeat="l in list" >
<a href="#firsttab" ng-click="tab = 1" data-toggle="tab" >
{{l.title}} </a>
<div class="tab-content" >
<div id="firsttab" ng-click="tab = 1" ng-
show="tab===1">
Id: {{l.id}} <br>
Name: {{l.Name}} <br>
Content: {{l.content}} <br>
TemplateFile: <div ng-include="l.templateUrl"></div>
</div>
</ul>
</div>
</li>
model.js(Just change the code of this file with the code I have written below. It will give you desired result)
We have to provide delay to broadcast to make it work.
define(['jquery','ocLazyLoad','cssinjector'], function() {
var app=angular.module('App', ['angular.css.injector','oc.lazyLoad']);
app.controller('mycontroller', ['$scope','$ocLazyLoad','cssInjector','$rootScope','$timeout',
function($scope,$ocLazyLoad,cssInjector,$rootScope,$timeout) {
alert("modal-loaded");
$ocLazyLoad.load("http://localhost:8080/tabs/js/modal1.js")
.then(function(){
alert("modal1 loaded");
$scope.view="http://localhost:8080/tabs/view.html";
cssInjector.add("http://localhost:8080/tabs/style.css");
});
// ARRAY
var items=[
{
Name:"tab1",
id:1
},
{
Name:"tab2",
id:2
},
{
Name:"tab3",
id:3
}
];
$timeout(function(){
$rootScope.$broadcast('itmObj', items);
},0);
}]);
angular.element(function() {
angular.bootstrap(document, ['App']);
});
});
If you broadcast like this in parent controller
$scope.$broadcast('itmObj',{ itemsArray: items});
Then you can use the on-catch in child controller like
and you eill have the items array in args.itemsArray
$scope.$on('itmObj', function (event, args) {
var x = args.itemsArray; // args.itemsArray is your items from parentcontroller
});
Trying to add a promise on lazyloading the modalController and modal view will look like this
Modal.js
define(['jquery','ocLazyLoad','cssinjector'], function() {
var app=angular.module('App', ['angular.css.injector','oc.lazyLoad']);
app.controller('mycontroller', ['$scope','$ocLazyLoad','cssInjector',
function($scope,$ocLazyLoad,cssInjector) {
alert("modal-loaded");
// ARRAY
var items=[{
Name:"tab1",
id:1
},{
Name:"tab2",
id:2
},{
Name:"tab3",
id:3
}];
var lazyLoadModal1 = function(){
var deferred = $q.defer();
$ocLazyLoad.load("http://localhost:8080/tabs/js/modal1.js")
.then(function(){
alert("modal1 loaded");
$scope.view="http://localhost:8080/tabs/view.html";
cssInjector.add("http://localhost:8080/tabs/style.css");
deferred.resolve();
},function(){
deferred.reject();
});
return deferred.promise;
};
var init = (function(){
lazyLoadModal1().then(function(){
$scope.$broadcast('itmObj', {item:items});
});
})();
}]);
View.html
<div ng-controller="modalcontroller">
<div ng-repeat="vm in itemsArray">
<p>{{vm.Name}}</p>
<p>{{vm.id}}</p>
</div>
</div>
Modal1.js
angular.module('App', ['angular.css.injector','oc.lazyLoad'])
.controller("modalcontroller", ['$scope','$ocLazyLoad','cssInjector',
function($scope,$ocLazyLoad,cssInjector){
alert("In modal Controller");
$scope.$on("broadcast-started", function (event, data){
$scope.itemsArray=data.item;
console.log($scope.itemsArray);
});
}]);

Displaying data in ng-grid by clicking on an <a> element in the sidebar

I have a view in an angularjs application with a sidebar, where I can choose my insurers. By clicking on an insurer, I want my ng-grid show me some insurer's data. Now I can select the insurer, and see the <div class="well well-sm"> changes.
Here is my angular controller:
app.controller('ReportsInsurerPaymentsCtrl', ['$scope', '$http', '$filter', 'toaster', '$state', '$modal', function ($scope, $http, $filter, toaster, $state, $modal) {
$scope.insurer_payments = [];
$scope.insurer_payments = [];
$scope.insurer_payment = {};
$scope.gridOptions = {
data: "insurer_payment",
rowTemplate: '<div ng-style="{\'cursor\': row.cursor, \'z-index\': col.zIndex() }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell {{col.cellClass}} " ng-cell></div>',
columnDefs: [
{
field: "date",
displayName: "Date",
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>',
width: 100
},
{
field: "amount",
displayName: "Amount",
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>'
},
{
field: 'comment',
displayName: 'Comment',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>',
}
],
$scope.refresh = function () {
var p = {
name: $scope.filterOptions.filterText,
pageNumber: (allPages >= $scope.pagingOptions.currentPage) ? $scope.pagingOptions.currentPage : $scope.pagingOptions.currentPage = 1,
pageSize: $scope.pagingOptions.pageSize,
sortInfo: sb.join("")
};
$http({
url: "reports/insurer_payments.json",
method: "GET",
params: p
}).success(function (data, insurer_payment) {
$scope.totalServerItems = data.insurerPaymentsCount;
$scope.insurer_payments_count = data.total_insurer_payments_count;
$scope.insurer_payments = data.insurer_payments;
$scope.insurer_payment = data.insurer_payment;
if (insurer_payment) {
$scope.insurer_payment = $filter('orderBy')($scope.insurer_payments, 'name')[0];
} else {
$scope.insurer_payment = $filter('filter')($scope.insurer_payments, {name: insurer_payment.name})[0];
}
if ($scope.insurer_payments) $scope.insurer_payment.selected = true;
$scope.showContent = true;
if ($scope.gridOptions.ngGrid) {
$scope.gridOptions.ngGrid.buildColumns();
}
}).error(function () {
});
}, 100);
};
$scope.selectInsurerPayment = function(item){
angular.forEach($scope.insurer_payments, function(item) {
item.selected = false;
});
$scope.insurer_payment = item;
$scope.insurer_payment.selected = true;
};
$scope.refresh();
}]);
A part of a view:
<a ng-repeat="insurer_payment in insurer_payments | orderBy:'name'"
class="list-group-item m-l"
ng-class="{'select m-l-none': insurer_payment.selected }"
ng-click="selectInsurerPayment(insurer_payment)">
<span class="block text-ellipsis m-l-n text-md" ng-class="{'m-l-none': insurer_payment.selected }">
{{ insurer_payment.name }}
</span>
</a>
<div class="well well-sm">
<div class="row">
<div class="col-sm-4">
<strong>Commission: {{insurer_payment.commission}}</strong>
</div>
<div class="col-sm-4">
<strong>Insurer Ppayment: {{insurer_payment.insurer_payment}}</strong>
</div>
<div class="col-sm-4">
<strong>Inequality: {{insurer_payment.commission - insurer_payment.insurer_payment}}</strong>
</div>
</div>
</div>
<div class="table-responsive">
<div ng-grid="gridOptions" class="gridStyle">
</div>
</div>
And a part of a rails controller:
def index
insurer_payments = current_company.insurers.map do |insurer|
{
commission: insurer.contracts.pluck(:commission).sum.to_f,
name: insurer.name,
insurer_payment: insurer.insurer_payments.pluck(:amount).sum.to_f,
id: insurer.id
}
end
insurer_payment = current_company.insurers.map do |insurer|
{
amount: insurer.insurer_payments.pluck(:amount).map { |x| x.to_f },
comment: insurer.insurer_payments.pluck(:comment),
date: insurer.insurer_payments.pluck(:date),
id: insurer.id
}
end
total_insurer_payments_count = current_company.insurers.map do |insurer|
insurer.insurer_payments.count
end
insurer_payments_count = current_company.insurer_payments.count
respond_to do |format|
format.json { render json: { insurer_payments: insurer_payments, insurer_payment: insurer_payment,
total_insurer_payments_count: total_insurer_payments_count,
insurerPaymentsCount: insurer_payments_count } }
end
end
So, how it can be done, by selecting an insurer to see the corresponding data?
I am not sure on this, since I don't have all of your code, but you may want to try some of the changes I have below.
Because ng-repeat has it's own scope, iterating through insurer_payment in insurer_payments is conflicting with insurer_payment on scope. When you loop through the insurer_payments, you are modifying the value of insurer_payment each time.
I would change
$scope.gridOptions = {
data: "insurer_payment",
to
$scope.gridOptions = {
data: [];
Since the data is an array, not a string.
Within the success callback of $http, you need to set gridOptions.data (unless this is elsewhere, I don't see where the grid is)
.success(function (data, insurer_payment) {
$scope.gridOptions.data = data;
...
}
And the selectInsurerPayment function:
$scope.selectInsurerPayment = function(item){
angular.forEach($scope.insurer_payments, function(item) {
item.selected = false;
});
$scope.selectedInsurerPayment = item;
$scope.insurer_payment.selected = true;
};
And finally, in the well in your HTML, change references to insurer_payment to selectedInsurerPayment, ex:
<strong>Commission: {{selectedInsurerPayment.commission}}</strong>
Old Solution
In ng-repeat:
ng-click="selectInsurerPayment(insurer_payment)"
to
ng-click="selection.insurer_payment = insurer_payment"
In the well,
<div class="well well-sm">
to
<div class="well well-sm" ng-if="selection.insurer_payment">
and change the references to insurer_payment to selection.insurer_payment.{variable}, example:
<strong>Commission: {{selection.insurer_payment.commission}}</strong>

AngularJS $routeParams / service not fetching data from JSON

On test-detail.html page (partial view), data from respective json files are not fetched/displayed, i.e. the controller TestDetailCtrl is called in test-detail.html (as can be seen on a working alert button), but params curly brackets in view (test-detail.html) are empty.
However ListController for test-list.html works and fetches the tests.json.
File structure:
index.html
(tests)
tests.json (content correctly displayed in test-list.html)
a.json
b.json
(js)
(partials)
(css)
partials/test-list.html:
<form action="" data-ng-repeat="test in tests | orderBy:orderProp">
<input type="checkbox" data-ng-model="item.selected" data-ng-change="change(item)">
<a href="#/tests/{{test.id}}">
<img data-ng-src="{{test.imageUrl}}" alt="{{test.name}}" class="test-thumb">
</a>
<a href="#/tests/{{test.id}}">
{{ test.name }}
</a><br />
</form>
partials/test-detail.html (where none of the data are displayed and all checkmarks are false):
<div class="main">
<img data-ng-src="{{mainImageUrl}}"/>
<h2>{{ test.name }}</h2>
<p>{{ test.description }}</p>
Customization:
<ul>
<li>Test items: {{test.customization.items | checkmark }}</li>
<li>Test duration: {{test.customization.duration | checkmark }}</li>
</ul>
</div>
route provider in js/app.js:
app.config(['$routeProvider',
{$routeProvider
.when('/tests',
{templateUrl: 'partials/test-list.html', controller: 'ListController'})
.when('/tests/:testId',
{templateUrl: 'partials/test-detail.html', controller: 'TestDetailCtrl'})
.otherwise({redirectTo: '/tests'});
}]);
RESTful handling with js/services.js:
var appServices;
appServices = angular.module('appServices', ['ngResource']);
appServices.factory('Test', ['$resource',
function($resource){
return $resource('tests/:testId.json', {}, {
query: {method:'GET', params:{testId:'tests'}, isArray:true}
});
}]);
controllers.js:
var ctr = angular.module('myApp.controller', []);
ctr.controller('ListController', ['$scope', 'Test', function ($scope, Test)
{$scope.tests = Test.query(); /*works*/
$scope.orderProp = 'duration';}]);
ctr.controller('TestDetailCtrl', ['$scope', '$routeParams', 'Test', function($scope, $routeParams, Test)
{$scope.$on('$routeChangeSuccess', function() {
$scope.test = Test.get({testId: $routeParams.testId}, function(test) {
$scope.mainImageUrl = test.screenshots[0];
});
$scope.setImage = function(imageUrl) {
$scope.mainImageUrl = imageUrl;
};
$scope.hello = function(name) {
alert('Test ' + (name || 'works' + '!')); /*works*/
}
})}
]);
Example test-a.json:
[{
id: "test-a",
name: "test a",
description: "text ... bla",
"customization": {
"items": true,
"duration": false}
}]
I think you are mixing aspx partials with angular-arrays here.
Angular ng-repeat will work on client side only and will evaluate your scope.tests array when it finishes loading.
Your aspx partial (test-detail.html) will probably work server-side and will depend on you data-binding it with a container.
Edit: Your test-a.json looks strange... why is it encapsulated with brackets? (Why is it an array?) The partials/test-a.html is not made for arrays. Try this JSON (test-a.json):
{
id: "test-a",
name: "test a",
description: "text ... bla",
"customization": {
"items": true,
"duration": false}
}

How to refresh an ng-repeat list when the backing model has been updated via ng-click?

I'm rather new to AngularJS so I presume this is going to be something about confusing scope.
I'm trying to get a ng-repeat list watching a service on the scope to update when I push a new item to the service backing model from a ng-click anchor link.
An example failing fiddle is here: http://jsfiddle.net/znFwY/
JS:
'use strict';
angular.module('myApp', [])
.factory('Order', function () {
return {
packages: {
theList: [],
list: function () {
return this.theList;
},
push: function (p) {
if (p === undefined || !!this.theList[p.title]) return;
this.theList[p.title] = p;
console.log('pushed ' + p.title);
},
contains: function (p) {
return !!this.theList[p.title];
},
print: function () {
console.log(this.theList);
}
}
}
})
.controller('AppCtrl', function ($scope, $http, $location, Order) {
$scope.order = Order;
$scope.data = {
packages: [
{title: 'one'},
{title: 'two'},
{title: 'three'},
]
};
})
;
HTML:
<div ng-app="myApp">
<div ng-controller="AppCtrl">
<ul id="package-list">
<li ng-repeat="package in data.packages | orderBy:package.order">
<a ng-click="order.packages.push(package)" ng-class="{selected: order.packages.contains(package)}">{{package.title}}</a>
</li>
</ul>
<ul id="basket-list">
<li ng-repeat="package in order.packages.list() | orderBy:package.order"> {{package.title}}</li>
</ul>
<a ng-click="order.packages.print()">print list</a>
</div>
</div>
Thanks

Resources