I am new to Angular. Not sure why directive is not working below. Searched some articles. Nothing helps
angular.module('oneApp', []).controller('OneAppController', function($scope){
//Some Logic
}).directive('dvReplaceText', ['$interval', '$compile', function($interval, $compile) {
return {
restrict: 'A',
link: function(scope, element, attr) {
scope.$watch(scope.data, function(value) {
element.html(value);
});
}
}
}]);
HTML:
<body ng-app="oneApp">
<div ng-controller="OneAppController">
<input class="input-data-box" ng-model="data" dv-replace-text=""/>
</div>
</body>
JSFiddle Link
Should be:
scope.$watch('data', function(value) {
...
});
You should change $watch like this :
scope.$watch('data', function(value) {
element.html(value);
console.log(value);
});
Demo : http://jsfiddle.net/vikashvverma/LzLe71ft/6/
Try like this
angular.module('oneApp', []).controller('OneAppController', function($scope){
//Some Logic
}).directive('dvReplaceText', ['$interval', '$compile', function($interval, $compile) {
return {
restrict: 'A',
link: function(scope, element, attr) {
scope.$watch("data", function(value) {
//element.value(value);
console.log(value);
});
}
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="oneApp">
<div ng-controller="OneAppController">
<input class="input-data-box" ng-model="data" dv-replace-text=""/>
</div>
</body>
var app=angular.module('myApp', []);
app.controller('OneAppController', function($scope){
//Some Logic
console.log("data loaded");
});
app.directive('dvReplaceText', function() {
return {
link: function(scope, element, attr) {
scope.$watch(scope.data, function(value) {
element.html(value);
});
}
}
});
HTML
<div ng-controller="OneAppController">
<input class="input-data-box" ng-model="data" dv-replace-text/>
</div>
Here is the working model JSFIDDLE LINK
Related
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.
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
}
}
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']);
});
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');
})
});
}
};
})
Why is my ng-click not working when I appended it with a button? The same ng-click is working when I initially loaded the button.
app.controller('demoCtrl', function() {
this.clk = '<button ng-click="dctrl.click()">Button</button>';
this.click = function() {
alert('clicked');
}
})
app.directive('btnClick', function() {
return {
restrict: 'A',
scope: {
actionBtn: '='
},
link: function(scope, element, attrs) {
element.append(scope.actionBtn);
}
}
})
HTML
<body ng-controller="demoCtrl as dctrl">
<div btn-click action-btn="dctrl.clk"></div>
</body>
http://plnkr.co/edit/QPKXfGd9s7HzLvEfKvbG?p=preview
Update
I've also tried this way but no luck
element.append($compile(scope.actionBtn)(scope));
You need to compile an new dom element created manually for angularjs to work on it so
app.directive('btnClick', ['$compile', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.append($compile(scope.$eval(attrs.actionBtn))(scope));
}
}
}])
var app = angular.module('my-app', [], function() {})
app.controller('demoCtrl', function() {
this.clk = '<button ng-click="dctrl.click()">Button</button>';
this.click = function() {
alert('clicked');
}
})
app.directive('btnClick', ['$compile',
function($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.append($compile(scope.$eval(attrs.actionBtn))(scope));
}
}
}
])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="my-app" ng-controller="demoCtrl as dctrl">
<div action-btn="dctrl.clk" btn-click></div>
</div>