How to add a function to a angular object dynamical to the onclick or click event?
Adding onclick={{item.function}} or ng-click={{item.function}} won't work
JS
angular
.module('app', [])
.controller('MainController', ['$scope', function($scope) {
$scope.test = function() {
alert(1);
};
$scope.items = {
'item1': {
name: 'Item1',
function: 'test()' // Not calling
}
};
}]);
Html
<html ng-app="app">
<body ng-controller="MainController">
<ul ng-repeat="item in items">
<li ng-bind="item.name" ng-click="item.function"></li>
</ul>
</body>
</html>
Not working demo
http://codepen.io/anon/pen/jqEKRP
In controller:
...
'item1': {
name: 'Item1',
f: $scope.test
}
...
In template:
<li ng-bind="item.name" ng-click="item.f()"></li>
http://codepen.io/bparnikel/pen/bpNjoE
Related
When I click a button, the controller will get data from some $http service callback function and will $broadcast it on $scope. Then, in the directive, I have a listener to get the data and do some logic. But, when I am using ng-repeat on button for several formats, the listener will get fired for all ng-repeat items when I click on each button. How can I make the listener to get fired only for the clicked button? Please see the sample code below.
var app = angular.module('demoApp', []);
app.controller('MyCtrl', function($scope) {
var myCtrl = this;
myCtrl.getFile = function(){
var response = 'some data';
$scope.$broadcast('downloadFile', {'response': response});
}
});
app.directive('fileDownload', function(){
return {
restrict: 'A',
link: function(scope, elem, attrs){
var cancelEvent = scope.$on('downloadFile', function(event, args){
console.log('called', args);
});
scope.$on('$destroy', function(){
cancelEvent();
});
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp">
<div ng-controller="MyCtrl as myCtrl">
<button ng-repeat="format in ['TXT','PDF','CSV']" ng-click="myCtrl.getFile()" file-download>{{ format }}</button>
</div>
</div>
In this sample you can figure out how can create directive using scope, i create a sample to get all formats get all lists, get checked list, get download format, on directive.
About your codes, actually response is true, because when we use some functions like [$broadcast] or ... on app run all data already sets in our scopes. but remember in this case you don't need to use $broadcast that because our actions are in-time and we can get them when we click on a function.
hope helps you my friend
var app = angular.module('app', []);
app.controller('ctrl', function ($scope) {
var self = this;
self.lists = [
{ name: "A"},
{ name: "B"},
{ name: "C"},
{ name: "D"}
];
self.getFile = function () {
console.log('controller', "done");
}
});
app.directive('fileDownload', function ($filter) {
return {
restrict: 'A',
scope: {
fileDownload: "=",
list: "="
},
link: function (scope, elem) {
elem.on("click", function () {
var filter = $filter("filter")(scope.list, { checked: true });
console.log('from directive, all list', scope.list);
console.log('from directive, checked list', filter);
console.log('from directive, download format', scope.fileDownload);
});
}
}
});
<!DOCTYPE html>
<html ng-app="app" ng-controller="ctrl as self">
<head>
<title></title>
</head>
<body>
<small>list</small>
<ul>
<li ng-repeat="list in self.lists">
<input type="checkbox" ng-model="list.checked"/>
{{list.name}}
</li>
</ul>
<small>download format</small>
<button ng-repeat="format in ['TXT','PDF','CSV']" ng-click="self.getFile()" list="self.lists" file-download="format">{{ format }}</button>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</body>
</html>
I think it will help you
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp">
<div ng-controller="MyCtrl as myCtrl">
<span ng-repeat="format in ['TXT','PDF','CSV']">
<span get-file="myCtrl.getFile({data: data})" file-download title="format"></span>
</span>
</div>
</div>
</body>
<script type="text/javascript">
var app = angular.module('demoApp', []);
app.controller('MyCtrl', function($scope) {
var myCtrl = this;
myCtrl.getFile = function(data) {
var response = 'some data';
console.log(response);
console.log(data);
// $scope.$broadcast('downloadFile', {'response': response});
}
});
app.directive('fileDownload', function() {
return {
restrict: 'A',
template: "<button ng-click='callFn()'>{{title}}</button>",
scope: {
title: '=',
getFile: '&'
},
link: function(scope, elem, attrs, ctrl) {
scope.callFn = function(){
scope.getFile({data: scope.title});
}
// var cancelEvent = scope.$on('downloadFile', function(event, args) {
// console.log('called', args);
// });
// scope.$on('$destroy', function() {
// cancelEvent();
// });
}
}
});
</script>
</html>
Here is my html
<li
ng-repeat="myElement in myList">
<input
type="checkbox" value="myElement"
ng-model="checkState"
ng-click="myDirective.updateSelectedElement(myElement, checkState)"/>
<div>
{{myElement.name}}
</div>
</li>
I have a $broadcast event such that
$scope.$on('myEvent', function(event, data){
// Change the checkbox state for the checkbox that have the same name in data
})
The question is since my checkbox are all isolated scopes, I don't have access to it, is there a way to access the checkbox that have specific myElement.name
Thanks
Doing it through the rootscope will solve your problem
app.controller("ControllerA", ["$scope", "$rootScope", function($scope, $rootScope){
$rootScope.$broadcast("myEvent");
}]);
app.controller("ControllerB", ["$scope", "$rootScope", function($scope, $rootScope){
$rootScope.$on('myEvent', function(event, data){
$scope.checkState = true;
})
}]);
Here is a working example of code that I wrote to show how checkboxes could be programmatically checked and unchecked from outside of the directive using events. I use buttons in this example, but you could call the methods from inside the controller as well.
Example in Plunker
Also, as a best practice, if you are dispatching an event from rootScope and listening for it on rootScope as well, use $emit instead of $broadcast so that the event starts and ends at rootScope and is not broadcast down the scope chain.
Angular Code
angular.module('app', [
]).controller('MainController', ['$scope', '$rootScope', function ($scope, $rootScope) {
$scope.list = [{label: 'Camaro'}, {label: 'Chevette'}, {label: 'Corvette'}];
$scope.checkItem = function (label, status) {
$rootScope.$emit('checkItemEvent', {label: label, check: status});
};
}])
.directive('checkboxDirective', function ($rootScope) {
return {
restrict: 'AE',
template: '<input type="checkbox" ng-model="item.checkState"/><span>{{item.label}}</span>',
require: 'ngModel',
scope: {
item: '=ngModel'
},
link: function ($scope) {
console.log('$scope.item', $scope.item);
$rootScope.$on('checkItemEvent', function (event, data) {
console.log('data', data);
if (data.label === $scope.item.label) {
$scope.item.checkState = data.check;
}
});
}
};
});
HTML
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>Checkbox demo</h1>
<ul>
<li ng-repeat="item in list">
<checkbox-directive ng-model="item"></checkbox-directive>
</li>
</ul>
<div>
<button ng-click="checkItem('Corvette', true)">Check Corvette</button>
<button ng-click="checkItem('Corvette', false)">Uncheck Corvette</button>
</div>
</body>
</html>
I want to write HTML code inside of DIV after getting data from service but it doesn't work. These are my html and js codes. How can I fix?
Thanks.
index.html:
<html>
<head>
<title>AngularJS</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular-sanitize.js"></script>
<script src=script></script>
</head>
<body ng-app="myApp">
<div ng-controller="myController">
<div ng-bind-html="htmlcode">
</div>
</div>
</body>
</html>
script.js:
(function(angular) {
'use strict';
angular.module('myApp', ['ngSanitize'])
.controller('myController', ['$window', '$scope', '$http', function($window, $scope, $http) {
html = "<ul><li>Item-1<ul><li>SubItem-1</li></ul></li><li>Item-2</li></ul>";
$scope.htmlcode= html;
var res = $http.post(service_url);
res.success(function(result, status, headers, config) {
});
}]);
})(window.angular);
script1.js:
(function(angular) {
'use strict';
angular.module('myApp', ['ngSanitize'])
.controller('myController', ['$window', '$scope', '$http', function($window, $scope, $http) {
var res = $http.post(service_url);
res.success(function(result, status, headers, config) {
html = "<ul><li>Item-1<ul><li>SubItem-1</li></ul></li><li>Item-2</li></ul>";
$scope.htmlcode= html;
});
}]);
})(window.angular);
RESULT (script1.js):
Item 1
Item 2
SubItem-1 is not shown as a sub item of Item-1
RESULT (script.js):
Item 1
SubItem-1
Item 2
Do not manipulate html inside the controller use diectives or services for that. This should be done with an ng-repeat instead.
(function(angular) {
'use strict';
angular.module('myApp', ['ngSanitize'])
.controller('myController', ['$window', '$scope', '$http', function($window, $scope, $http) {
$scope.items = [];
var res = $http.post(service_url);
res.success(function(result, status, headers, config) {
$scope.items.concat(result.items);
});
}]);
})(window.angular);
// template
<body ng-app="myApp">
<div ng-controller="myController">
<ul class="items">
<li ng-repeat="item in items">
{{item.name}}
<ul class="sub-items">
<li ng-repeat="subitem in item.subItems">{{subitem.name}}</li>
</ul>
</li>
</ul>
</div>
</body>
// items.json
{
"items": [
{
"name": "item1",
"subItems": [
"name": "subItem1"
]
}
]
}
I am having a problem loading a set of JSON data with NG CLICK. Without the clickButton function the data loads fine. Is my JSON data structured properly? Here is my fiddle. Click [here] (http://jsfiddle.net/al321/08rjqv4k/3/ "mouse over")
$scope.items = [
{
"Name":"Sam",
"Address":"Street",
"Phone":"111",
"status":"Available"
},
{
"Name":"Tom",
"Address":"Road",
"Phone":"222",
"status":"Busy"
},]
--js
var app = angular.module('myApp', []);
app.controller('myController',
['$scope', '$http', function($scope, $http) {
$scope.clickButton = function() {
$http.get('data.json').success(function(data) {
$scope.items = data.items;
});
}
}]);
Plunker
JS
var app = angular.module('myApp', []);
app.controller('myController', ['$scope', '$http', function($scope, $http) {
$scope.clickButton = function() {
$http.get('data.json').success(function(data) {
$scope.items = data;
});
}
}]);
Markup
<body ng-controller="myController">
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click='clickButton()'>Load Data</button>
<ul ng-repeat="item in items">
<li ng-repeat="(key, val) in item">{{key}}: {{val}}
</li>
</ul>
</div>
</div>
</body>
JSON
[
{
"Name":"Sam",
"Address":"Street",
"Phone":"111",
"status":"Available"
},
{
"Name":"Tom",
"Address":"Road",
"Phone":"222",
"status":"Busy"
}
]
Is this what you are trying to accomplish?
Just replace the contents of the clickButton() function with your ajax calls.
You forgot to put the () on ng-click="clickButton(). You need to actually call the function.
Plunker
To add the search functionality you mentioned in the comment, just add a filter to the first ng-repeat:
ng-repeat="item in items| filter: {Name: search}"
Plunker with search
I am using angular-translate in my project but I am unable to define a controller that has a dependency injection of $translate. The code isn't executed in the browser. I checked JSHint already...
index.html
<html ng-app='ngApp'>
<body>
<div ng-controller="orderFormCtr">
<ul>
<li>{{'TITLE' | translate}}</li>
<li translate="TITLE"></li>
</ul>
</div>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-translate/angular-translate.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
angular.module('ngApp', ['pascalprecht.translate']);
// this code works
angular.module('ngApp').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('en', {
TITLE: 'Hello'
});
$translateProvider.translations('de', {
TITLE: 'Hallo'
});
}]);
// the browser ignores this code
angular.module('ngApp').controller('orderFormCtr', ['$scope', '$translate', function ($scope, $translate) {
alert("Controller Code executed");
}]);
var app = angular.module('ngApp', ['pascalprecht.translate']);
// this code works
app.config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('en', {
TITLE: 'Hello'
});
$translateProvider.translations('de', {
TITLE: 'Hallo'
});
$translateProvider.preferredLanguage('en');
//or translateProvider.determinePreferredLanguage()
}]);
// the browser ignores this code
app.controller('orderFormCtr', ['$scope', '$translate', function ($scope, $translate) {
alert("Controller Code executed");
}]);
http://jsbin.com/miqazola/1/