I have the example below:
HTML:
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<p>Result is {{result}}!</p>
<output-content data="name"></output-content>
</body>
JavaScript:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.result = "no";
$scope.changeLabel = function() {
$scope.result = 'yes';
}
});
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
scope: {
data: '=',
result: '='
},
controller: 'MainCtrl'
};
});
outpuContent.html:
<div>
{{data}}
<button ng-click="changeLabel()">Change</button>
</div>
Plunker is: http://plnkr.co/edit/uzSrGcyQLeRNEIH7IXBf
I would like the result to be 'yes' when I click on the 'Change' button.
It doesn't work.
Could you please explain to me how to write the directive to do so ?
Regards.
You define variable in directive scope, but do not pass it. Just pass
"result" into directive. E.g:
<output-content data="name" result="result"></output-content>
I forked your plunkr: http://plnkr.co/edit/12FXjUsVdPXhPIQ1mlHt?p=preview
Hope it helpful.
In directive, delete scope . Now like This.. this will be work..
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
controller: 'MainCtrl'
};
});
Scope is not needed. Kindly delete the scope.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.result = "no";
$scope.changeLabel = function() {
$scope.result = 'oh yeah';
}
});
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
controller: 'MainCtrl'
};
});
Related
In below code, controllerAs not working with widget and filter directive.
Can you please help me to fix this.
I couldn't figure out where exactly I'm doing wrong. :-(
Expected output:
Widget directive should print the "From widget controller".
Filter directive should print the "From filter directive".
I reproduced the issue here, please check.
HTML:
<div ng-app="myApp">
<body-dir>
<icon-dir>
<filter-dir>
</filter-dir>
</icon-dir>
<widget-dir>
</widget-dir>
</body-dir>
</div>
JS:
var myApp = angular.module('myApp', []);
myApp.controller('filterController', function filterController($scope) {
var vm = this;
vm.test = "From filter directive";
alert("filter");
return vm;
});
myApp.controller('widgetController', ['$scope', function widgetController($scope) {
var oki = this;
oki.widget = "From widget controller";
alert("widget");
return oki;
}])
myApp.directive('bodyDir', function() {
return {
restrict: 'E',
link: function($scope) {
alert('body-dir');
}
};
});
myApp.directive('widgetDir', function() {
return {
restrict: 'E',
controller: 'widgetController',
controllerAs: 'oki',
template: "<span>{{oki.widget}}</span>",
link: function($scope) {
alert('widget-dir');
}
};
});
myApp.directive('filterDir', function() {
return {
controller: 'filterController',
controllerAs: 'vm',
restrict: 'E',
template: "<span>{{vm.test}}</span>",
link: function($scope) {
alert('filter-dir');
}
};
});
myApp.directive('iconDir', function() {
return {
restrict: 'E',
link: function($scope) {
alert('icon-dir');
}
};
});
As far as I remember, controllerAs was introduced in AngularJS v1.2 but in your jsfiddle you are using v1.0.1. That is why controllerAs is not working for widget and filter directives.
Been trying to figure this out for too long now. Maybe someone can shed some light:
Am experimenting with custom directives and as an exercise I'm trying to create a method within the custom directive's controller that can be called from a simple button within the view. But the method isn't being called, even though I can see the method (using console) as a property within isolated scope object. Any ideas please?
HTML:
<my-dir>
<p>My dir content</p>
<p><button ng-click="hideMe()">Hide element with isolated scope</button></p>
</my-dir>
JS:
var app = angular.module('myApp', []);
app.directive('myDir', function() {
return {
restrict: 'EA',
scope: {},
controller: ['$scope', function ($scope) {
$scope.hideMe = function(){
console.log('hideMe called');
};
}]
};
})
You have to declare your template inside the directive using template: property or inside an external .html file using templateUrl:"path/to/template.html"
Example using template :
var app = angular.module('myApp', []);
app.directive('myDir', function() {
return {
restrict: 'EA',
scope: {},
template : '<p>My dir content</p><p><button ng-click="hideMe()">Hide me</button></p>',
controller: ['$scope', function ($scope) {
$scope.hideMe = function(){
console.log('hideMe called');
};
}]
};
})
Example using templateUrl :
var app = angular.module('myApp', []);
app.directive('myDir', function() {
return {
restrict: 'EA',
scope: {},
templateUrl : 'my-dir.tpls.html',
controller: ['$scope', function ($scope) {
$scope.hideMe = function(){
console.log('hideMe called');
};
}]
};
})
Template : my-dir.tpls.html
<p>My dir content</p>
<p><button ng-click="hideMe()">Hide me</button></p>
HTML:
<my-dir></my-dir>
You can try this,
Directive:
app.directive('myDir', function() {
return {
restrict: 'EA',
scope: {},
link: function($scope, element, attrs) {
$scope.hideMe = function() {
alert('hideMe called');
}
}
}
});
HTML:
<div ng-controller="MyCtrl">
<my-dir>
<p>My dir content</p>
<p>
<button ng-click="hideMe()">Hide element with isolated scope</button>
</p>
</my-dir>
</div>
DEMO
I have an issue with my AngularJS code.
It seems I can't access my directive scope from my controller.
The directive
app.directive('PaginatedText', function(){
return {
restrict: 'E',
scope: {
text: '='
},
controller: 'PaginatedTextController',
templateUrl: '/frontend/views/paginated-text.html'
};
})
The controller
app.controller('PaginatedTextController', ['$scope', function($scope){
$scope.page = 1;
$scope.limit = 200;
console.log($scope, $scope.text);
}]);
The directive call
<paginated-text text="character.long_description"></paginated-text>
The template
<p>
{{text}}
<button>read more</button>
</p>
The printed console.log:
Any idea why console.log($scope.text) print undefined ?
Directive names must start with lowercase!
app.directive('paginatedText',
angular.module('app', [])
.run(function($rootScope) {
$rootScope.character = {
long_description: 'LirumLarum'
};
})
.directive('paginatedText', function() {
return {
restrict: 'E',
scope: {
text: '='
},
controller: 'PaginatedTextController',
template: '<p>{{text}}<button>read more</button></p>'
};
})
.controller('PaginatedTextController', ['$scope',
function($scope) {
$scope.page = 1;
$scope.limit = 200;
console.log($scope, $scope.text);
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<div ng-app="app">
<paginated-text text="character.long_description"></paginated-text>
</div>
I have the example below.
HTML:
<body ng-controller="MainCtrl as MgtCtrl">
<p>Hello {{MgtCtrl.name}}!</p>
<p>Result is {{MgtCtrl.result}}!</p>
<output-content data="MgtCtrl.name" result="MgtCtrl.result"></output-content>
</body>
JavaScript:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
var MgtCtrl = this;
MgtCtrl.name = 'World';
MgtCtrl.result = "no";
MgtCtrl.changeLabel = function() {
alert('changeLabel');
MgtCtrl.result = 'yes';
}
});
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
scope: {
data: '=',
changeLabel: '&',
result: '='
},
controller: 'MainCtrl',
controllerAs: 'MgtCtrl'
};
});
ouputContent.html:
<div>
{{data}}
<button ng-click="MgtCtrl.changeLabel()">Change</button>
</div>
Plunker is: http://plnkr.co/edit/BW8VDyCaRnRgxE8I9JJy
I would like the result to be 'yes' when I click on the 'Change' button.
It doesn't work because of the named controller.
Could you please explain to me how to write the directive to do so ?
Regards.
You never was binding the scope variables to the named controller in the directive.
You must add the attribute bindToController: true to the directive definition like this plunker:
http://plnkr.co/edit/2QdnkpeuTM6adG9KoyJT?p=preview
Directive code:
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
scope: {
data: '=',
changeLabel: '&',
result: '='
},
controller: 'MainCtrl',
controllerAs: 'MgtCtrl',
bindToController: true
};
});
This go to add the data and result binding to the respective directive controller.
I think in this case you don't need to specify controller in the directive.
app.directive('outputContent', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'outputContent.html',
scope: {
data: '=',
changeLabel: '&',
result: '='
}
};
});
Also html shoul be updated:
<body ng-controller="MainCtrl as MgtCtrl">
<p>Hello {{MgtCtrl.name}}!</p>
<p>Result is {{MgtCtrl.result}}!</p>
<output-content data="MgtCtrl.name" result="MgtCtrl.result" change-label="MgtCtrl.changeLabel()"></output-content>
</body>
I have a directive defined like so:
angular.module('directives.myInput', [])
.directive('myInput', function($parse, $http, $sce){
return {
restrict: 'E',
template: '<input type="text" ng-model="searchStr" />',
controller: function($scope){
$scope.keyPressed = function(event){
$scope.showDropdown = true;
.
.
.
}
}
};
});
And then I have a button in html and directive above declared like so:
<div ng-controller="IndexCtrl">
<button ng-click="startNewLog()">Start</button>
<div ng-controller="ItemNewCtrl">
<myInput />
</div>
</div>
I want to change/initialize ng-model="searchStr" model on a button ng-click. How can I do that?
Thanks guys,
Jani
If I understand you right, first of all you need call child controller with $broadcast. Since we don't use isolate scope, we just call directive method from child controller:
[Short answer]
No isolate scope example
Demo 1 Fiddle
For isolate scope, I would map value to directive that listens on value change automatically:
Isolate scope example
Demo 2 Fiddle
[Full answer]
No isolate scope example
HTML
<div ng-controller = "IndexCtrl">
<button ng-click="startNewLog()">Start</button>
<div ng-controller="ItemNewCtrl">
<my-input></my-input>
</div>
</div>
JS
var app = angular.module('myModule', []);
app.controller('IndexCtrl', function ($scope) {
$scope.startNewLog = function(){
$scope.$broadcast('someEvent');
};
});
app.controller('ItemNewCtrl', function ($scope) {
$scope.$on('someEvent', function() {
$scope.callDirective();
});
});
app.$inject = ['$scope'];
app.directive('myInput', function(){
return {
restrict: 'E',
template: '<input type="text" ng-model="searchStr" />',
controller: function($scope){
$scope.searchStr;
$scope.keyPressed = function(event){
$scope.showDropdown = true;
}
},
link: function(scope, elm, attrs) {
scope.callDirective = function() {
scope.searchStr = 'callDirective';
};
}
};
});
Isolate scope example
HTML
<div ng-controller = "IndexCtrl">
<button ng-click="startNewLog()">Start</button>
<div ng-controller="ItemNewCtrl">
<my-input my-model='contInput'></my-input>
</div>
</div>
JS
var app = angular.module('myModule', []);
app.controller('IndexCtrl', function ($scope) {
$scope.startNewLog = function(){
$scope.$broadcast('someEvent');
};
});
app.controller('ItemNewCtrl', function ($scope) {
$scope.contInput = '';
$scope.count = 0;
$scope.$on('someEvent', function() {
$scope.contInput = 'hey mate';
});
});
app.$inject = ['$scope'];
app.directive('myInput', function(){
return {
restrict: 'E',
scope:{searchStr: '=myModel'},
template: '<input type="text" ng-model="searchStr" />',
controller: function($scope){
$scope.searchStr;
$scope.keyPressed = function(event){
$scope.showDropdown = true;
}
}
};
});