I am using & (expression binding) operator in isolated scope of a directive but I am unable to trigger function on the parent controller . There should be output on the console but I am receiving none.
Here in the HTML part:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Directive &</title>
<script type="text/javascript" src="angular.min.js"></script>
<script src="isolate_scope_&.js"></script>
</head>
<body ng-app="isolate_scope">
<div ng-controller="isolateScopeController">
<b>Ctrl Data</b>
<div ng-repeat="person in persons">
<p>{{person.name}}</p>
</div>
<b>Directive Data</b>
<div ng-repeat="person in persons">
<friends frnd="person.name"></friends>
</div>
<my-button isolatedFunction="printScopeToFile()"></my-button>
</div>
</body>
</html>
Here goes the JS part :
angular.module('isolate_scope', [])
.controller('isolateScopeController', function($scope){
$scope.persons = [
{
name:"tanmay",
age:"28"
},
{
name: "James",
age:"28"
},
{
name:"Rylan",
age:"26"
},
{
name:"Aditya",
age:"23"
}
];
$scope.printScopeToFile = function(){
console.log("printng to file.....");
for(var i in $scope.persons){
console.log("Name = " + $scope.persons[i].name + " Age = " + $scope.persons[i].age);
}
};
})
.directive('friends',function(){
return {
restrict :'E',
template: '<input type="text" ng-model="name">',
scope :{
name:'=frnd'
}
};
})
.directive('myButton',function(){
return {
restrict: 'E',
template: '<button ng-click="isolatedFunction()">callParentfunction</button>',
scope : {
isolatedFunction:"&"
}
};
});
Fiddle for the same: http://jsfiddle.net/v51kob1q/
The attribute isolatedFunction in your <my-button isolatedFunction...> directive should need to be isolated-function, dash-delimited attributes
Related
I have 2 nested ng-repeat and boolean, which will hide the loading div, but loading div is hiding before all content is rendered. Boolean depends on a callback function which gets all data.
<tr ng-repeat="package in packages track by $index">
<td> {{ pack.Name }}</td>
<td>
<select ng-hide="package.spinStart" class="form-control" ng-model="package.selectedVersion">
<option ng-repeat="pack in package.allPackageVersions track by $index"
value="{{pack.Version}}"
ng-hide="pack.shouldHide"
ng-disabled="!expertModeOn && pack.shouldDissable"
ng-style="!expertModeOn && pack.shouldDissable && {'color':'#ddd'}">
{{pack.NuGetPackageId}} | {{pack.Version}} | {{pack.Published}}
</option>
</select>
How I call the function when all 2 nested loops are finished?
I tried with $watch statement and directive.
Thanks You!
can you use $last?
<!DOCTYPE html>
<html data-ng-app="myApp">
<head>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body data-ng-controller="testController">
<div ng-repeat="package in packages">
{{package.name}}
<div ng-repeat=" pkg in package.selectedVersion" ng-init="$last && call()">
{{pkg.name}}
</div>
</div>
<script>
angular
.module('myApp', [])
.run(function($rootScope) {
$rootScope.title = 'myTest Page';
})
.controller('testController', ['$scope',
function($scope) {
$scope.packages = [{
name: 'test1',
selectedVersion: [{
name: 'test_ver1'
}, {
name: 'test_ver2'
}, {
name: 'test_ver3'
}]
}, {
name: 'test2',
selectedVersion: [{
name: 'test_ver1'
}, {
name: 'test_ver2'
}, {
name: 'test_ver3'
}]
}];
var counter = 0
$scope.call = function() {
counter++
if (counter == $scope.packages.length) {
alert("All loops finished");
}
}
}
])
</script>
</body>
</html>
You could use a directive which emits an event when the outer loop finishes.
You can reuse this directive in any loop, just resubscribe to the event.
app.directive('onRepeatFinish', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
// $last is a boolean set by angular inside ng-repeats
if (scope.$last) {
// Wait for view to fully render
$timeout(function() {
// Emit upwards the tree
scope.$emit('repeatFinished');
});
}
}
};
});
In your controller, subscribe to the event:
$scope.$on('repeatFinished', function() {
$scope.showLoader = false;
});
Usage in view:
<tr ng-repeat="package in packages track by $index" on-repeat-finish>
Here is my custom directive code
(function () {
var app = angular.module('CustDirMod', []);
var custdirCtrl = function ($scope) {
$scope.Person = {
Name: 'Jagan868',
address: {
street: '10 Donwstreet',
city: 'North Avenue',
state: 'Los Angeles'
},
friends: [
'Friend1',
'Friend2',
'Friend3'
]
};
};
var custDirectivewithBinding = function () {
return {
templateUrl: "Friends.html",
restrict: "E",
controller: function ($scope) {
$scope.KnightMe = function (Person) {
Person.rank = "Knight";
}
}
}
};
app.controller('CustDirCtrl', custdirCtrl);
app.directive("custDirectiveBinding", custDirectivewithBinding);
})();
and here is my template html
<div class="panel panel-primary">
<div class="panel-heading">
{{ Person.Name }}
</div>
<div class="panel-body">
<div ng-show='!!Person.address'>
<h4>Address :
</h4>
{{Person.address.street}}
<br />
{{Person.address.city}}
<br />
{{Person.address.state}}
</div>
<h4>Friends :</h4>
<br />
<ul>
<li ng-repeat='friend in Person.friends'>
{{friend}}
</li>
</ul>
<div ng-show="!!Person.rank">
Rank : {{Person.rank}}
</div>
<button ng-show="!Person.rank" class="btn btn-success" ng-click="KnightMe(Person)">Knight Me</button>
</div>
</div>
Now the following final html page where i'm using the above custom directive
<!DOCTYPE html>
<html ng-app="CustDirMod">
<head>
<title>Simple Directives - Angularjs</title>
<script src="Scripts/jquery-3.1.1.js"></script>
<link href="Content/bootstrap.css" rel="stylesheet" />
<script src="Scripts/bootstrap.js"></script>
<script src="Scripts/angular-1.5.8.js"></script>
<script src="Scripts/CustomDirective.js"></script>
</head>
<body ng-controller="CustDirCtrl" class="container" style="padding-top:30px;">
<cust-directive-binding></cust-directive-binding><br /><br />
</body>
</html>
Now i tried to add isolated scope in my custom directive as follows
var custDirectivewithBinding = function () {
return {
templateUrl : "Friends.html",
restrict: "E",
scope: {
userdata: "="
},
controller: function($scope){
$scope.KnightMe = function (Person) {
Person.rank = "Knight";
}
}
}
};
and then in the html page as follows
<body ng-controller="CustDirCtrl" class="container" style="padding-top:30px;">
<cust-directive-binding userdata="Person"></cust-directive-binding><br /><br />
</body>
After adding the isolated scope named as 'userdata' i'm not getting any data in UI. But if i remove that 'userdata' isolated scope from both js & html file its working fine. How to resolve this issue.
P.S: I don't want name the isolated scope local property name same as "Person". I just want it to be something different so that i can distinguish easily.
You don't have a scope property Person in the directive , you renamed it to userdata when you created the isolated scope.
You either need to change the template to now use userdata instead of Person or change the name of userdata to Person so the template will work
scope: {
userdata: "="
}
// in view
{{ userdata.Name}}
Or
<cust-directive-binding Person="Person">
scope: {
Person: "="
}
// in view
{{ Person.Name}}
Because now inside your directive template data will be available with isolated scope variable userdata. To fix the issue you could use userdata instead of Person every where on template. But instead of doing that I'd suggest you to use alias on isolated scope like Person: "=userdata". Where it says userdata will be attribute inside directive data will be available with Person name.
scope: {
Person: "=userdata"
},
I have a Kendo model instance (person for this example) and watching it is modified or not by using dirty property.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Kendo + Angular</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
</head>
<body>
<div ng-app="app" ng-controller="MainCtrl">
<div>Person name: {{ person.name }}</div>
<input type="text" name="name" ng-model="person.name"> <!-- This input don't work -->
<button ng-click="foo()">Foo</button> <!-- This button work because I call person.set method manually -->
<div>This person is modified? {{ person.dirty }}</div>
</div>
<script>
var Person = kendo.data.Model.define({
id: "personId", // the identifier of the model
fields: {
"name": {
type: "string"
},
"age": {
type: "number"
}
}
});
angular.module("app", ["kendo.directives"])
.controller("MainCtrl", function ($scope) {
$scope.person = new Person({
name: "John Doe",
age: 42
});
$scope.foo = function () {
$scope.person.set('name', "Kendo");
}
});
</script>
</body>
</html>
But when I type to text box dirty don't change because Angular ngModel doesn't fire Kendo "change" event. My real app have dozens of models like this, so is there any way to fix this automatically???
Thanks.
You can write a directive to replace for ng-model,
<input type="text" name="name" k-bind-model="person.name">
angular.module('app')
.directive("kBindModel", ["$parse", function ($parse) {
return {
restrict: "A",
scope: false,
link: function (scope, element, attributes, controller) {
var key = null;
var strs = attributes.kBindModel.split('.');
if (strs && strs.length > 1) {
key = strs[1];
}
var model = scope[strs[0]];
element.change(function () {
scope.$apply(function () {
model.set(key, element.val());
});
});
scope.$watch(attributes.kBindModel, function (n, o) {
element.val(n);
});
}
}
}]);
I am learning AngularJS from codeSchool and I was making a simple hello world app , initially it was being rendered properly but after some time It didn't work at all. I am not able to detect the bug , please help
Here is the code for html file
<!DOCTYPE html>
<html ng-app="store">
<head>
<title>Angular Code School</title>
<link rel="stylesheet" href="bootstrap.min.css">
</head>
<body>
<script type="text/javascript" src="angular.js"></script>
<script type="text/javascript" src="app.js"></script>
I am {{4+6}}
{{"Hello +"World"}}
<div ng-controller="StoreCtrl as store">
<div ng-repeat="product in store.products| orderBy:'-price'">
<h2>Name :{{product.name}} </h2>
<h2>Price:{{product.price | currency}} </h2>
<h2>Description:{{product.description}} </h2>
<button ng-show="product.canPurchase">Add To Cart </button>
<section ng-controller="PanelCtrl as panel">
<ul class="nav nav-pills">
<li ng-class="{'active':panel.isSelectedTab(1)}"><a href ng-click="panel.selectTab(1)"> Description</a></li>
<li ng-class="{'active':panel.isSelectedTab(2)}"><a href ng-click="panel.selectTab(2)">Specs</a></li>
<li ng-class="{'active':panel.isSelectedTab(3)}"><a href ng-click="panel.selectTab(3)">Reviews</a></li>
</ul>
<div ng-show="panel.isSelectedTab(1)">This is description div</div>
<div ng-show="panel.isSelectedTab(2)">This is Specification Section</div>
<div ng-show="panel.isSelectedTab(3)">This is Reviews section</div>
</section>
</div>
</div>
</body>
</html>
appTest.js
var app = angular.module('store', []);
app.controller('StoreCtrl', ['$scope', function ($scope) {
this.products = gems;
}])
gems = [{
name: 'Dodecahedron',
price: 2.95,
description: 'This is the description of Dodecahedron'
canPurchase: false;
},
{
name:'Diamond',
price: 5.95,
description: 'Diamond is the most luxuriest gem of all.'
canPurchase:true;
}]
app.controller('PanelCtrl', ['$scope', function ($scope) {
this.tab=1;
this.selectTab = function(setTab) {
this.tab = setTab;
};
this.isSelectedTab = function(checkTab){
return this.tab===checkTab;
}
}])
The structure of my directory is like
root/
angular.js
appTest.js
index.html
Here is the page with console
appTest.js
var app = angular.module('store', []);
app.controller('StoreCtrl', function() {
this.products = gems;
});
app.controller('PanelCtrl', function() {
this.tab = 1;
this.selectTab = function(setTab) {
this.tab = setTab;
};
this.isSelected = function(checkTab) {
return this.tab === checkTab;
};
});
var gems =
[{
name: 'Dodecahedron',
price: 2.95,
description: 'This is the description of Dodecahedron',
canPurchase: false
},
{
name: 'Diamond',
price: 5.95,
description: 'Diamond is the most luxuriest gem of all.',
canPurchase: false
}];
and in index.html
{{"Hello" +"World"}} should be {{"Hello" + "World"}}
You're messing a double quote:
{{"Hello +"World"}}
should be:
{{"Hello " + "World"}}
Check your console for javascript error.
Three issues:
Modify the hello words as below
{{ "Hello" + "World"}}
in your appTest.js,
add the comma after description fields of the 'gem'
remove the ";" semicolon after "canPurchase"
in your html file
ensure you are including "appTest.js" and not just "app.js"
I must do a website. On this website when you click on img it adds a text to the div.
It must has directives and controllers i dont have a clue how to do this...
<!DOCTYPE HTML>
<html>
<head>
<script src="http://code.angularjs.org/1.2.7/angular.min.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="Stylesheet" type="text/css" href="styles/style.css">
<title>AngularJS System Zamówień</title>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope) {
$scope.data = new Date();
$scope.hambureger ={
nazwa: 'Hambureger',
cena: '5',
}
$scope.crips = {
nazwa: 'Crips',
cena: '4',
}
$scope.cola = {
nazwa: 'Coca-Cola',
cena: '3',
}
$scope.show = function() {
}
}
myApp.directive1('myDir1', function () {
return {
restrict: 'A',
template: '<br>{{hamburger.nazwa}}'
};
});
myApp.directive2('myDir2', function () {
return {
restrict: 'A',
template: '<br>{{frytki.nazwa}}
};
});
myApp.directive3('myDir3', function () {
return {
restrict: 'A',
template: '<br>{{cola.nazwa}}'
};
});
});
</script>
</head>
<body>
<h1 class="ladne"><center>System zamówień żarcia</center></h1>
<div class="d1" ng-app="myApp" ng-controller="myCtrl">
<img src="styles/img/cola.gif" ng-click=""></img>
<img src="styles/img/fryt.gif" ng-click=""></img>
<img src="styles/img/ham.gif" ng-click=""></img>
<br>
<div class="zam">
Data Zamówienia: {{data |date:'yyyy-MM-dd'}}
<br>
Twoje zamówienie: //HERE ANGULAR MUST ADD A TEXT
</div>
</div>
</body>
</html>
It's really hard for me to do this...
So let's explain one more time:
When u click on img, text is added to div(class="zam"), when you press next img it adds new text in new line. Here are 3 diffrent imgs Crips, Hambureger 'n' cola