I don't think this information is enough to completely make sense but I just some direction on this. or if you want I can share the complete code with you in floobit
I am trying to put this array from API into a seller array.
this.fetchSellers = function () {
var date = new Date().toISOString();
$http.get('/api/sellers', {params: {auctionDate: date}})
.success(function (sellers) {
sellers && sellers.length && ($scope.sellers = sellers);
});
};
I am trying to put this one of the value Seller.symbol into the array list below.
$scope.sellers = []
It able to load into ng-option like
<select class="form-control" ng-model="auction.seller" ng-options="o.id as o.symbol for o in sellers" required></select>
But the question is, I am not able to pass the value into another controller in the table.
code for HTML
<tbody class="auction-group" ng-repeat="a in auctions">
<tr>
#*auction *#
<td>{{ acv('auctionDate', a) }}</td>
#*seller*#
<td>{{ a.seller }}</td>
Code for ng
this.tableComplexFieldDict = {
auctionDate: {
label: 'Auction',
cacheKey: 'auctionDate',
getCacheValue: function (a) {
return moment(a.startAt).format('MM/DD/YY');
}
},
facility: {
label: 'Facility',
cacheKey: 'facility',
getCacheValue: _.property('contract.facility')
},
seller: {
label: 'Seller',
cacheKey: 'seller',
getCacheValue: function (a) {
return a.seller;
}
},
in order to do that you have to use another service. Ideally, you can pass data between controller to service vice versa. so just create another service and include it in which ever controller you want to pass data to.
here is example
or
// declare the app with no dependencies
var myApp = angular.module('myApp', []);
myApp.factory('Data', function(){
return { FirstName: '' };
});
myApp.controller('one', function( $scope, Data ){
$scope.Data = Data;
});
myApp.controller('two', function( $scope, Data ){
$scope.Data = Data;
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://rawgit.com/angular/bower-angular/master/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp">
<h3>write something in text box it will be printed by both controller</h3>
<div ng-controller="one">
<input type="text" ng-model="Data.FirstName"><!-- Input entered here -->
<br>Controller 1 : <strong>{{Data.FirstName}}</strong><!-- Successfully updates here -->
</div>
<hr>
<div ng-controller="two">
Controller 2: {{Data.FirstName}}<!-- How do I automatically updated it here? -->
</div>
</div>
</body>
</html>
Passing data between controllers can be done in 3 ways:
Shared service both controllers use with set get data functions
Using direct data binding through root scope as a medium to store read data from
(terrible abusage of root scope)
through events
For me, best practice is Using a store and read service ;)
Related
Basically I am trying to access controller scope property from directive's controller function. I am doing it through $parent property. It works fine for static directive but not for dynamically created directive.
please have a look on my plunker
Dynamic Directive
In a plunker, when I click on folder with Id = 1. all goes good and folder path shows as "1 path". Same goes for folder with Id = 2.
But it does not work for dynamically appended folder with Id = n
I am somewhat new to angular. Any help would be much appreciated.
Updated Answer
In light of the latest requirement:
I am trying to call the directive function (i.e updateMap) from
controller.
You can use a Service to share variables between Controllers and Isolated Directives. In the example below, the Service holds the function that will be executed. Each directive when clicked will set the Service's function to it's own updateMap() function. Then the Controller in onFolderPathClicked() calls the Services executeFunction() function, which runs the previously set function.
script.js:
var module = angular.module('testApp', []);
module.service('updateMapService', function(){
var updateMapFunction = null;
this.executeFunction = function(){
updateMapFunction();
};
this.setFunction = function(fn){
updateMapFunction = fn;
};
});
module.controller('crtl', function($scope, updateMapService) {
$scope.onFolderPathClicked = function(){
updateMapService.executeFunction();
};
});
module.directive('folder', function($compile) {
return {
restrict: 'E',
scope: {
id: '#',
folderPath: "="
},
template: '<p ng-click="onFolderClicked()">{{id}}</p>',
controller: function($scope, $element, updateMapService) {
$scope.onFolderClicked = function(){
updateMapService.setFunction(updateMap);
addFolder();
};
var addFolder = function() {
$scope.folderPath = $scope.id + ":click here for calling update map";
var el = $compile('<folder id="n" folder-path="folderPath"></folder>')($scope);
$element.parent().append(el);
};
var updateMap = function() {
alert('inside updateMap()..' + $scope.id);
}
}
}
});
index.html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-app="testApp" ng-controller="crtl">
<div>FolderPath : <a ng-click="onFolderPathClicked()">{{ folderPath }}</a> </div>
<folder id="1" folder-path="folderPath"></folder>
<folder id="2" folder-path="folderPath"></folder>
</div>
</html>
You could also move folder-path into a Service to save from passing it in as an attribute. The code smell being that passing it in as an attribute means doing so twice, whereas in a Service it means setting it and getting it once (code reuse).
Not sure what is going on , but I'm not getting anything to display on my web page with ng-repeat with template.
Here is a picture image showing the data
This pic shows my console.log output with array of objects
NO IDEA why doesn't just display on the web page!
Devices: Array[17]
0 : Object
Aid : "....."
...
1 : Object
Angular controller with function
(function () {
'use strict';
angular.module('app').controller('DeviceController', DeviceController);
function DeviceController($http){
var vm = this;
var dataService = $http;
//dataService.get("/api/Product")
vm.devices = [];
deviceList();
function deviceList() {
dataService.get("http://localhost:42822/api/device")
.then(function (result) {
vm.devices = result.data;
//debugger;
console.log(vm.devices);
},
function (error) {
handleException(error);
});
}
function handleException(error) {
alert(error.data.ExceptionMessage);
}
}
})();
HTML
<html>
<head> </head>
<body>
<div ng-app="app" ng-controller="DeviceController as vm">
<div>test</div><br>
<table>
<tbody>
<tr ng-repeat="device in vm.devices">
<td>{{device.Aid}}</td>
<td>{{device.DeviceId}}</td>
</tr>
</tbody>
</table>
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<!--<script src="~/Scripts/angular.min.js"></script>-->
<script src="./app/app.module.js"></script>
<script src="./app/device.controller.js"></script>
</html>
NO IDEA why doesn't just display on the web page!
As you have data inside Devices object of response, then you need to change your assignment in ajax resolve like below.
vm.devices = result.data.Devices;
I'd suggest you to change your response from server, instead of sending Devices collection in Devices object, directly send it in response.
OR you could also make changes on HTML directly, but it wouldn't be good way to go.
<tr ng-repeat="device in vm.devices.Devices">
<td>{{device.Aid}}</td>
<td>{{device.DeviceId}}</td>
</tr>
I've got a function in my controller very easy that just stamp a console.log. I need to conditioning a button using a function but inside the ng-repeat the controller repeats everything many times! Is it normal? Is it possible avoid this? Thanks. An example here http://plnkr.co/edit/sME67gQEZQSLI9FOwEAG?p=preview
relative code:
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.4.5" data-semver="1.4.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="DigestApp">
<div ng-controller="UserCtrl as uc">
<h1>Please open the console to see</h1>
<ul>
<li ng-repeat="user in uc.users" ng-class="uc.userClasses(user)">
{{user.name}}
<button ng-if="uc.isUserEnabled(user)"
ng-click="uc.disableUser(user)">Disable</button>
</li>
</ul>
</div>
</body>
</html>
javascript:
angular.module("DigestApp", [])
.controller('UserCtrl', function(User) {
var vm = this;
vm.users = User.list();
vm.isUserEnabled = function(user) {
console.log('isUserEnabled');
return user.active;
};
vm.userClasses = function(user) {
console.log('userClasses');
return []
.concat(user.active ? ['user-active'] : [])
.concat(user.loggedIn ? ['user-logged-in'] : [])
.concat(user.isMe ? ['user-is-me'] : [])
.join(' ');
};
vm.disableUser = function(user) {
user.active = false;
};
})
.factory('User', function() {
return {
list: function() {
return [{
name: "me",
active: true,
loggedIn: true,
isMe: true
}];
}
};
});
Yes, this is normal. There is no way that angular can tell whether the result of the function will have changed, so it calls it on every digest loop. If you want to avoid that you should calculate the value once and set the result as an attribute on the user object.
<li ng-repeat="user in uc.users" ng-class="user.classes">
{{user.name}}
<button ng-if="user.active"
ng-click="uc.disableUser(user)">Disable</button>
</li>
and in the controller add some code to precalculate a user.classes attribute on each user object (and to update it when you change the state of the model).
Please update your li in the HTML to the below. I got it working here http://plnkr.co/edit/Cx5OZaY0dhmBT4WLYZpX?p=info.
<li ng-repeat="user in uc.users" ng-class="{ 'user-active': user.active, 'user-logged-in': user.loggedin, 'user-is-me': user.isme }">
{{user.name}}
<button ng-if="user.active" ng-click="uc.disableUser(user)">Disable</button>
</li>
By using a function in your ng-class and ng-if it was evaluating to often. You can just pass the scope variables instead.
I'm trying to use AngularJS in my cfm files to display data from cfquery resultset.
I used below code in my cfm file.I'm not able to see any output.
P.S. I'm really new to AngularJS. So if anyone can please help me out here it would be great.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html ng-app="Demo">
<head>
<link rel="stylesheet" href="/Applications/_Common/style.css" type="text/css">
</head>
<body>
<cfsetting enablecfoutputonly="Yes">
<CF_GetProjectData project_number=349246 query_name="GetProject">
<div ng-controller="DemoController">
<div ng-repeat="number in project">
{{number.project_number}} - {{number.project_name}}
</div>
<!-- <input name="imprint" type="text" size="10" ng-model="first">
<p>{{first}}</p> -->
</div>
<cfoutput>
<script language="JavaScript" src="/CFIDE/scripts/wddx.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script language="text/javascript">
var theProjectArray; < cfwddx action = "CFML2JS"
input = "#GetProject#"
toplevelvariable = "theProjectArray" >
</script>
<script>
var Demo = angular.module("Demo", []);
Demo.controller("DemoController", function($scope) {
$scope.project = theProjectArray;
alert(theProjectArray);
});
</script>
</cfoutput>
<cfsetting enablecfoutputonly="No">
</body>
</html>
I am not sure about Angular.js but based on the code you have posted, it seems, you need to wrap ng-controller div in cfoutput. This is because you have set enablecfoutputonly="Yes". So only the content inside cfoutput will be rendered.
I'm a CF developer that's currently learning Angular as well. First of all Angular is a MVC framework and will work for you best of you follow the rules of Separation of Concern (SoC). I know unless you are using Object Relational Mapping (ORM) in CF this is counter intuitive but it will save you so much hassle and trouble shooting later.
For your problem right now though i would
combine both script blocks.
your variable theProjectArray is defined with var so it's not
global. Are you sure it's making it into your controller?
the line toplevelvariable = "theProjectArray" > ... is the greater
than sign a type-o?
After you've done those i would console.log(theProjectArray); right after it's defined. Then console.log(theProjectArray); again in your controller to ensure it's getting passed in properly.
Just for your reference here is a very basic example of a controller and a factory in angular calling a CFC. Since i've been doing things this way the only time i use ColdFusion is to retrieve data and model it. It's simplified my code and logic quite a bit and has allowed me to do a lot more now that i'm not leaning on ColdFusion.
var myapp = angular.module("test.myapp", [])
myapp.controller("MyController", function($scope, getevent) {
$scope.myData = {};
$scope.myData.doUpdate = function(item, event) {
getevent.GetProgram(item).success(function(data, status, headers, config) {
console.log(data.DATA);
$scope.test = data.DATA;
$scope.test.DATE = new Date(data.DATA.DATESTART);
});
getevent.GetProgram(item).error(function(data, status, headers, config) {
console.log("FAILED: "+item);
alert("AJAX failed!");
});
}
});
myapp.factory('getevent', function($http){
return {
GetProgram: function(item) {
var programInfo = '/foundation/cfc/calendar.cfc?method=getevent&eventid='+item;
return $http.get(programInfo);
}
};
});
I'm trying to get my head around scopes and after dredging through a number of blogs, stack overflow answers and the docs I am still stuck.
angular.module('app', [])
.factory('alphabet', function () {
data = [
'c',
'b',
'a'
];
return {
get : function () {
return data;
},
set : function (val) {
data.push(val);
}
};
})
.controller('AlphaCtrl', function (alphabet) {
this.alphabet = alphabet;
})
.directive('sortableTable', function () {
return {
scope : {
"param" : '#'
},
link : function (scope) {
console.log(scope.param);
}
};
})
;
HTML:
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div ng-controller="AlphaCtrl as alpha">
<table sortable-table param="{{alpha.alphabet}}">
<thead>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</body>
</html>
What I would like to do is be able to access a service/factory that's being used in an outer controller from within a directive. So for example when I handle a click event I can add items to the data. That seems to be a good way of keeping things decoupled but I am open to suggestions there.
The problem at hand is that 'param' is undefined. I've also tried using '&' but that's not doing anything for me. Could someone put me on the path to Angular righteousness?
I would inject the service directly into the directive:
.directive('sortableTable', function (alphabet) {
return {
scope : {},
link : function (scope) {
console.log(alphabet);
}
};
})
This is indeed a good way of keeping things decoupled, if this is a directive that is used across controllers and views.
Edit for a bit more complex solution: It is possible to do it by injecting the service into the scope of the directive, though I would not recommend it if you don't need to switch services on the fly, since the method above is easier. I could see some use cases though, if you would want to input a different service (with the same get/set structure) in another controller for example. Here's how you could do it via scope:
.controller('myController', function($scope, alphabet) {
$scope.alphabet = alphabet;
})
.directive('myDirective', function(){
return {
scope: {
service: '='
},
template: '<div ng-bind="service.get()"></div>'
}
})
And in the template:
<div data-my-directive service="alphabet"></div>
The trick here is using service: '=' as this creates a two-way binding between the scope-variable in the controller (which is bound to the service) and the scope-variable in the directive. http://jsfiddle.net/vt52bauu/2/
I don't think the get/set is going to work the way you are expecting in an Angular factory.
this.alphabet = alphabet.get();