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.
Related
I want to send that to my directive but I want that data to stay updated if the data in the controller changes.
// Controller
angular
.module('app')
.controller('IndexController', IndexController)
IndexController.$inject = [];
function IndexController() {
var vm = this;
vm.name = 'John';
newName = function() {
vm.name = 'Brian';
}
newName();
}
// Directive
angular
.module('app')
.directive('userName', userName);
userName.$inject = ['$document'];
function userName($document) {
var directive = {
restrict: 'EA',
template: '<div id="user"></div>',
replace: true,
scope: {
name: '='
},
link: function(scope, elem, attrs) {
console.log(scope.data);
}
}
return directive;
}
this is how I use the directive. the problem is that it always returns the first name and not the new name after the change in the controller.
<div ng-controller="indexController">
<user-name name="indexController.name">
</div>
thank you.
Try this, you just have to inject $scope into your Indexcontroller
angular
.module('app', [])
.controller('IndexController', function($scope) {
var vm = this;
vm.name = 'John';
vm.newName = function() {
vm.name = 'Brian';
console.log(vm.name);
}
//vm.newName();
})
.directive('userName', ['$document', function() {
var directive = {
restrict: 'E',
template: '<div id="user"></div>',
replace: true,
scope: {
name: '='
},
link: function(scope, elem, attrs) {
console.log(scope.name);
}
}
return directive;
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="IndexController as vm">
<user-name name="vm.name"></user-name>
<button ng-click="vm.newName()">Click</button>
</div>
Without using as in controller, you cannot use controller.prop inside the scope.
Inside the controlleryou need to call the method using its $scope or this.
Check the below code.
angular
.module('app', [])
.controller('IndexController', function($scope) {
$scope.name = 'John';
$scope.newName = function() {
$scope.name = 'Brian';
}
$scope.newName();
})
.directive('userName', ['$document', function() {
var directive = {
restrict: 'E',
template: '<div id="user"></div>',
replace: true,
scope: {
name: '='
},
link: function(scope, elem, attrs) {
console.log(scope.name);
}
}
return directive;
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="IndexController">
<user-name name="name"></user-name>
</div>
Here is my controller:
angular
.module('app')
.controller('MyCtrl', MyCtrl);
Viewer.$inject = [];
function MyCtrl() {
var vm = this;
vm.titles = ['Hello', 'world'];
}
My Directive:
angular
.module('app')
.directive('myDirective', myDirective);
myDirective.$inject = [];
function flPagesArea($compile) {
var directive = {
link: link,
restrict: 'EA',
template: '<div ng-repeat="title in vm.titles">{{title}}</div>'
};
return directive;
}
The result is:
<!-- ng-repeat= title in vm.titles -->
Is the problem with my usage of the controller as or I'm missing something.
Thank you.
Use the controllerAs option and the bindToController property. Also check the name of the function associated to directive. In your case, you never associate the flPagesArea function to directive declaration in the module.
angular
.module('app')
.directive('myDirective', myDirective);
myDirective.$inject = ['$compile'];
function myDirective($compile) {
var directive = {
link: link,
restrict: 'EA',
template: '<div ng-repeat="title in vm.titles">{{title}}</div>',
controller: 'MyCtrl',
controllerAs: 'vm',
bindToController: true
};
return directive;
}
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'
};
});
I want to create two directives that have the following structure:
<div ng-app="myApp">
<div ui-foo="test">
<div ui-bar="test2"></div>
</div>
</div>
First directive is uiFoo, the second one is uiBar.
To define these directives I have setup the following module definition:
angular.module('ui', []).directive('uiFoo',
function() {
return {
restrict: 'A',
link: function($scope, element, attrs) {
$scope.message = function() {
alert(1);
};
}
};
}
).directive('uiBar',
function() {
return {
restrict: 'A',
require: '^uiFoo',
scope: true,
link: function($scope, element, attrs, uiBarController) {
uiBarController.message();
}
};
}
);
angular.module('myApp', ['ui']);
The problem that I am experiencing is known as error/$compile/ctreq (Controller 'uiFoo', required by directive 'uiBar', can't be found!) and the documentation for it can be found here (https://docs.angularjs.org/error/$compile/ctreq?p0=uiFoo&p1=uiBar). I know, a little lackluster.
It doesn't seem to solve my issue.
I've created a JSFiddle for this which you can find here http://jsfiddle.net/A8Vgk/1187/
Thanks!
Like the error says, you're missing the controller on the uiFoo directive.
When you use the require: ^uiFoo, it tells Angular that you want to have access to the controller in the directive called uiFoo.
You didn't define a controller in that directive, so you get the error.
Just define the controller:
angular.module('ui', []).directive('uiFoo',
function() {
return {
restrict: 'A',
link: function($scope, element, attrs) {
$scope.message = function() {
alert(1);
};
},
controller: function($scope) {
this.message = function () {
alert("works!");
}
}
};
}
)
Working Fiddle.
my directive:
angular.module('matrixarMatrice', []).directive('mtxMatriceForm', function () {
return {
restrict: 'E',
templateUrl: 'views/matrice/matrice.html',
scope: {
matrix: '=',
isclicked: '=',
selectedprice: '&'
},
link: function (scope, element, attrs) {
...
scope.selected = function (prices) {
scope.selected.id = prices.id;
scope.selectedprice(prices);
};
}
};
});
my controller:
$scope.selectedprice = function (prices) {
console.log(prices);
};
my html:
<mtx-matrice-form matrix="matrix " isclicked="isclicked" selectedprice="selectedprice(prices)"></mtx-matrice-form>
In my directive when i select item i call my controller.
I want to exploit my object prices, but the problem i have at the moment is i have an undefined in my controller.
Does anyone know the correct way of doing this?
This is the one option that you can use to include controller inside a directive! There are other options as well. Hope it helps!
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'Lorem';
});
app.directive('directives', function() {
return {
restrict: 'E',
controller: function($scope, $element){
$scope.name = $scope.name + "impsum";
},
link: function(scope, el, attr) {
scope.name = scope.name + "Ipsum";
}
}
})
i have found this solution:
in my directive:
...
scope.selected = function (prices) {
scope.selected.id = prices.id;
scope.selectedprice({prices: prices});
};
...