i cant update variable via directive in angularjs - javascript

i want to make my variable true to false in directive..
the problem is that my directive console correct but in view can't be changed .
here is Plunker Link...
var app = angular.module('my-app', [], function () {
})
app.controller('AppController', function ($scope) {
$scope.test=true;
$scope.items = ["One", 'Two'];
})
app.directive('myDir', function () {
return {
restrict: 'E',
scope: {
myindex: '=',
myTest:'='
},
template:'<div>{{myindex}}</div>',
link: function(scope, element, attrs){
console.log('test', scope.myindex);
element.click(function(){
scope.myTest=false;
console.log(scope.myTest);
});
}
};
})

Pls check it out
var jimApp = angular.module("mainApp", []);
jimApp.controller('mainCtrl', function($scope){
$scope.test = true;
$scope.items = ["One", 'Two'];
})
.directive("myDir", function() {
return {
restrict : "E",
scope:{ myindex: '=', myTest:'=' },
template : "<div >Jimbroo{{myindex}} {{myTest}}</div>",
link: function(scope, element, attrs){
element.bind('click', function() {
scope.myTest = false;
scope.$apply();
});
}
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<div ng-app="mainApp" ng-controller="mainCtrl">
<div ng-repeat="item in items">
{{test}}
<my-dir myindex="$index" my-test="test" ></my-dir>
</div>
</div>

here is code updated
1 - use updated version of angularjs
2 - Use # in directive
var app = angular.module('my-app', [], function () {
})
app.controller('AppController', function ($scope) {
$scope.test=true;
$scope.items = ["One", 'Two'];
})
app.directive('myDir', function () {
return {
restrict: 'E',
scope: {
myindex: '#',
myTest:'#'
},
template:'<div>{{myindex}}</div>',
link: function(scope, element, attrs){
console.log('test', scope.myindex);
element.click(function(){
scope.myTest=false;
console.log(scope.myTest);
});
}
};
})
<!DOCTYPE html>
<html ng-app="my-app">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<link rel="stylesheet" href="style.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="AppController">
<div ng-repeat="item in items track by $index">{{test}}
<my-dir my-test="test" myindex='{{$index}}'></my-dir>
</div>
</body>
</html>

use scope.$apply to know your scope changes in angular
plnkr
var app = angular.module('my-app', [], function () {
})
app.controller('AppController', function ($scope) {
$scope.test=true;
$scope.items = ["One", 'Two'];
})
app.directive('myDir', function () {
return {
restrict: 'E',
replace: true,
scope: {
myindex: '#',
myTest:'#'
},
template:'<div>{{myTest}}</div>',
link: function(scope, element, attrs){
element.click(function(){
scope.$apply(function() {
scope.myTest=false;
console.log('called');
})
});
}
};
})

Related

How to attach event to dom created in link function

I know that dom created in template function can be attached to an event in controller.As:
angular.module('app', [])
.directive('appClick', function(){
return {
restrict: 'A',
scope: true,
template: '<button ng-click="click()">Click me</button> Clicked {{clicked}} times',
controller: function($scope, $element){
$scope.clicked = 0;
$scope.click = function(){
$scope.clicked++
}
}
}
});
As there is no scope in template so I have to use link function.
The same how can I achieve in link function. Like:
angular.module('app', [])
.directive('appClick', function(){
return {
restrict: 'A',
scope: true,
link:function(scope, element, attrs){
element.html('<button ng-click="click()">Click me</button> Clicked {{clicked}} times')
},
controller: function($scope, $element){
$scope.clicked = 0;
$scope.click = function(){
$scope.clicked++
}
}
}
});
How to attach event here.
In Angularjs when you want to attach some DOM to the existing DOM. You first have to compile it with the $compile service on the scope for which you want to use the template. This is because template contain Angular js template syntax. Below is the working snippets.
var myApp = angular.module('myApp', []);
myApp.controller('mainController', ['$scope', function($scope){
$scope.message = 'Welcome message';
}])
myApp.directive('myTemplate', ['$compile',function($compile) {
return {
restrict: 'A',
scope: true,
link: function(scope, element, attr) {
var el = $compile('<button ng-click="click()">Click me</button> Clicked {{clicked}} times')(scope);
element.append(el);
scope.clicked = 0;
scope.click = function(){
scope.clicked++
}
}
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="mainController">
{{message}}
<div my-template></div>
</div>
</div>
angular.module('app', [])
.directive('appClick', function(){
return {
restrict: 'A',
scope: true,
link:function(scope, element, attrs){
element.html('<button ng-click="click()">Click me</button> Clicked {{clicked}} times')
scope.clicked = 0;
scope.click = function(){
scope.clicked++
}
}
});
Achieve this without controller.

Angularjs limit to directive

I'm trying to make a filter be used as a directive in Angularjs 1.4
What I want to make is to limit string using limitTo filter but as a directive not (|) filter.
I made this but it's not working
charlimit.js directive
function controller($scope) {
$scope.length = 15;
}
angular.module('xApp')
.directive('charlimit', function () {
return {
restrict: 'A',
scope: {
limitTo: '#',
},
controller: ["$scope", controller]
};
});
index.html
<p charlimit="5"></p>
Do you have any thoughts?
Thanks.
var app = angular.module("xApp", []);
app.directive('charLimit', function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
var limitLength = parseInt(attrs.charLimit);
scope.limittext = scope.limittext.substring(0, limitLength);
return scope.limittext;
}
}
});
app.controller("IndexController", function($scope) {
$scope.limittext = 'Sample text';
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="xApp" ng-controller="IndexController">
<p char-limit="5">{{limittext}}</p>
</body>

Where to define a local function in a AngularJS Directive

Where do I have to define my function button() in the directive, such that pressing the button will trigger the function?
I don't want to use the outer scope of the app, I just want to use the local scope.
var app = angular.module("myApp", []);
app.directive('aaaa', function() {
return {
restrict: 'E',
scope: {
data: '=',
//this is not working: button: function(){console.log('hello from button');}
},
link: function(scope, element) {
element.append('hello');
element.append(' <button type="button" ng-click="button()">Click Me!</button> ')
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="myApp">
<aaaa></aaaa>
</div>
As #tymeJV said , you need to compile the html first and then call button() in directive controller
var app = angular.module("myApp", []);
app.directive('aaaa', function($compile) {
return {
restrict: 'E',
scope: {
data: '=',
//this is not working: button: function(){console.log('hello from button');}
},
link: function(scope, element) {
element.append('hello');
var htmlText = ' <button type="button" ng-click="button()">Click Me!</button> ';
var template = angular.element($compile(htmlText)(scope));
element.append(template);
},
controller: function($scope, $element){
$scope.button = function(){
console.log('button clicked');
}
}
}
});
I would advise to use angular templates instead of element.append, see example code below. Then you don't need all the compiler code 'n stuff.
You could also replace "template: 'hello
var app = angular.module("myApp", []);
app.directive('aaaa', function() {
return {
restrict: 'E',
scope: {
data: '='
},
link: function(scope, element) {
scope.button = function(){
console.log('hello from button');
};
},
template: 'hello <button type="button" ng-click="button()">Click Me!</button>'
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="myApp">
<aaaa></aaaa>
</div>
you can out under link
link: function(scope, element) {
element.append('hello');
element.append(' <button type="button" ng-click="button()">Click Me!</button> ');
scope.button=function(){
//content goes here
}
}

Angular.js ng-repeat callback

I need to send a callback when ng-repeat finishes, but my solutions don't work. In my last solution I used a directive to do it.
Markup:
<div class="results" ng-model="results">
<div class="empl-card" ng-repeat="empl in employees | filter: searchQuery" callback-on-end="alert('callback')">
...
</div>
</div>
directive:
app.directive("callbackOnEnd", function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
if (scope.$last) {
scope.$eval(attrs.callbackOnEnd);
}
}
};
});
Where could I have made a mistake?
I think you can do this with just ngInit as follows;
<div class="results" ng-model="results">
<div class="empl-card" ng-repeat="empl in employees | filter: searchQuery" ng-init="$last && alert('callback')">
...
</div>
</div>
You don't need a custom directive for doing this.
To achieve this you need to make a method in your controller and call that method when the ng-repeat ends :
(function() {
angular.element(document).ready(function() {
var app = angular.module('myApp', []);
app.controller("MyCtrl", function($scope, $timeout) {
$scope.names = ['A', 'B', 'C', 'D'];
$scope.onEnd = function() {
alert('all done');
};
});
app.directive("callbackOnEnd", function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
if (scope.$last) {
scope.$eval(attrs.callbackOnEnd);
}
}
};
});
angular.bootstrap(document, ['myApp']);
});
}());
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="MyCtrl" class="well">
<h3 ng-repeat="name in names" callback-on-end="onEnd()">{{name}}</h3>
</div>
Or you will have to eval the javascript code
app.directive("callbackOnEnd", function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
if (scope.$last) {
eval(attrs.callbackOnEnd);
}
}
};
});
(function() {
angular.element(document).ready(function() {
var app = angular.module('myApp', []);
app.controller("MyCtrl", function($scope, $timeout) {
$scope.names = ['A', 'B', 'C', 'D'];
$scope.onEnd = function() {
alert('all done');
};
});
app.directive("callbackOnEnd", function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
if (scope.$last) {
eval(attrs.callbackOnEnd);
}
}
};
});
angular.bootstrap(document, ['myApp']);
});
}());
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="MyCtrl" class="well">
<h3 ng-repeat="name in names" callback-on-end="alert('done')">{{name}}</h3>
</div>
Find good explanation here :
https://stackoverflow.com/a/15671573/3603806
Check here. Created custom directive for repeatEnd
http://plnkr.co/edit/YhGzYFOcVaVds7iAEWPn?p=preview
<h3 ng-repeat="name in names" repeat-end="onEnd()">{{name}}</h3>
app.js
angular.element(document).ready(function() {
var app = angular.module('repApp', []);
app.controller("MainCtrl", function($scope, $timeout) {
$scope.names = ['user1', 'user2', 'user3'];
$scope.onEnd = function() {
$timeout(function() {
alert('all done');
}, 1);
};
});
app.directive("repeatEnd", function() {
return {
restrict: "A",
link: function(scope, element, attrs) {
if (scope.$last) {
scope.$eval(attrs.repeatEnd);
}
}
};
});
angular.bootstrap(document, ['repApp']);
});

Why is change in service not updating the controller?

Can someone explain why my code is not working as expected?
I expect after clicking the button, the text should be updated. But apparently, it is not the case.
I really appreciate any help.
main.js
x = angular.module('app', []);
x.directive("changer", function(myService){
return {
restrict: "E",
template: "<button>click</button>",
replace: true,
link: function (scope, elem, attrs) {
elem.click(function () {
myService.item1 = 'updated';
scope.$apply();
})
}
}
});
x.service('myService', function () {
var item = {'item1': 1, 'item2': 2};
return {
item : item,
};
});
x.controller('myController', function ($scope, myService) {
$scope.item = myService.item;
});
main.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="main.js"></script>
</head>
<body ng-controller='myController'>
<changer></changer>
{{item.item1}}
</body>
</html>
Thanks!
It is easier and better use 'ng-click' inside your directive template please see demo below
x = angular.module('app', []);
x.directive("changer", function(myService) {
return {
restrict: "E",
template: "<button ng-click='update()'>click</button>",
replace: true,
link: function(scope, elem, attrs) {
scope.update = function() {
myService.item.item1 = 'updated';
}
}
}
});
x.service('myService', function() {
var item = {
'item1': 1,
'item2': 2
};
return {
item: item,
};
});
x.controller('myController', function($scope, myService) {
$scope.item = myService.item;
$scope.test = "dfsf"
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body>
<div ng-app="app">
<div ng-controller='myController'>
<pre>{{item| json}}</pre>
<changer></changer>
</div>
</div>
</body>

Categories