I have a simple angular directive I would like to pass value to.
<div my-component binding-foo="foo">
<strong>get:</strong> {{isolatedBindingFoo}} // get it to output foo?
</div>
HTML
<div my-component binding='foo'> ... </div>
JS
yourApp.controller('yourController', ['$scope', function($scope) {
$scope.isolatedBindingFoo = '';
}])
.directive('myComponent', function() {
return {
controller: 'yourController',
scope: {
'binding': '=binding'
},
link: function($scope, $element, attrs) {
$scope.isolatedBindingFoo = attrs['binding'];
}
}
});
http://fdietz.github.io/recipes-with-angular-js/directives/passing-configuration-params-using-html-attributes.html
Cheers
AngularJS mangles HTML attributes to JS properties. eg, binding-foo in HTML will be mangled to bindingFoo in JS, and vice-versa
var myModule = angular.module('myModule', [])
.controller('yourController', ['$scope', function($scope) {
$scope.isolatedBindingFoo = '';
}])
.directive('myComponent', function() {
return {
restrict:'E,A',
controller: 'yourController',
scope: true,
link: function($scope, $element, attrs) {
$scope.isolatedBindingFoo = attrs['bindingFoo'];
}
}
});
http://jsfiddle.net/b2xo0o5u/3/
But in the example case this should be enough:
angular.module('myModule', [])
.directive('myComponent', function() {
return {
restrict:'EA',
scope: {
'isolatedBindingFoo': '#bindingFoo'
}
}
});
http://jsfiddle.net/b2xo0o5u/4/
Related
I am trying to watch when an array in a service is updated. I update this array in the service using a function in a directive based controller. Now for some reason the watch function does not get called in the link function of the second directive. Why is watch not being called in the second directive. I am trying to update the scope of a variable in the second directive so that it updates when the first directive function updates the service.
The Service
var productServices = angular.module('productServices', ['ngResource']);
productServices.factory('PlayerListS', [function() {
var playerList = [];
function getList() {
console.log(playerList);
return playerList;
}
function addToList(name) {
playerList.push(name);
}
return {
addToList :addToList,
getList: getList
}
}]);
The Directives
'use strict';
bands.directive("player",['PlayerListS', function (PlayerlistS) {
return {
restrict: 'E',
scope: {
person:'#person',
add:'&add'
},
replace: false,
templateUrl: "partials/player.html",
controller: function($scope, $element, $compile) {
$scope.playerList = ["A", "B"];
$scope.add = function(name) {
PlayerlistS.addToList(name);
PlayerlistS.getList();
}
},
link: function(scope, el, attrs) {
}
};
}]);
bands.directive("playerList", ['PlayerListS', function (PlayerlistS) {
return {
restrict: 'E',
replace: false,
template: "<p>Test</p>",
controller: function($scope, $element, $compile) {
},
link: function($scope, $el,$attrs) {
console.log('added');
var x = PlayerlistS.getList()
/*THIS IS WHERE THE WATCH IS HAPPENING*/
$scope.$watch('x', function (newVal, oldVal) {
console.log("CHANGED");
}, true);
}
};
}]);
The Controller
var bands = angular.module('bands', []);
bands.controller('ViewHousesCtrl', ['$scope', '$element', '$routeParams', '$q',
function ViewHousesCtrl($scope, $element, $routeParams, $q) {
$scope.playerLis = ["A","B","C"];
}]);
HTML
<player ng-show="true" person="RandomName" add="add()"></player>
<player-list ng-show="true" ng-repeat="a in playerLis"></player-list>
What your watcher is really doing, is trying to watch a variable called x on the directive scope. But your variable x is just a regular local variable, so your watcher doesn't trigger. So what your watcher basically translates to is this:
$scope.$watch(function(scope){
return scope['x'];
}, function (newVal, oldVal) {
console.log("CHANGED");
}, true);
You can probably see why it doesn't trigger. There is no variable $scope.x. Instead you should try watching the service directly, by specifying the watch function. Like this:
$scope.$watch(function(){
return PlayerlistS.getList();
}, function (newVal, oldVal) {
console.log("CHANGED");
}, true);
You have a spelling mistake in your HTML, it should be:
<player-list ng-show="true" ng-repeat="a in playerList"></player-list>
I wan't to program a flexible angular directive with it's properties defined in an own, simple object.
Angular:
contentFactory.directive("listViewDir", function ($compile) {
return {
restrict: "E",
scope: {
datasource: '=',
config: '='
},
controller: function ($scope) {
return $scope.config.controller($scope);
},
link:
return $scope.config.link(scope, element, attrs);
}
}
});
Own Configuration Object:
contentFactory.controller("indexCtrl", function ($scope) {
$scope.config = oLiftTabs;})
var configurations = [{
controller: function ($scope) {
$scope.ButtonClicked = function () {
alert('Button wurde geklickt!');
}
return $scope;
},
link: function (scope, element, attrs){
var template = "... myTemplate ..";
element.html(template);
$compile(element.contents())(scope);
},
}]
While my solution for the controller works well, it doesn't for the link.
Is there a more proper way for my approach? Can I realize access in my encapsulated method to the services (like $compile) without declaring it in the directive declaration?
Is this what you're trying to achieve? You didn't make it clear where you expect this object to live so I've assumed you want it a parent controller. This doesn't feel like a good idea but without knowing more about your use case it's hard to say.
DEMO
html
<body ng-controller="MainCtrl">
<list-view-dir config="config"></list-view-dir>
</body>
js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $compile) {
$scope.config = {
controller: function ($scope) {
$scope.ButtonClicked = function () {
alert('Button wurde geklickt!');
}
return $scope;
},
link: function (scope, element, attrs){
var template = '<button ng-click="ButtonClicked()" > Alert</button>';
element.html(template);
$compile(element.contents())(scope);
},
};
});
app.directive("listViewDir", function(){
return {
restrict: "E",
scope: {
datasource: '=',
config: '='
},
controller: function ($scope) {
return $scope.config.controller($scope);
},
link: function(scope, element, attrs){
return scope.config.link(scope, element, attrs);
}
};
});
Update
From your comments it sounds like you need to use a factory. Maybe something like this? It feels pretty ugly but it could be what you're looking for.
DEMO2
var app = angular.module('plunker', []);
app.factory('directiveConfigurations', function($compile){
var configurations = {
'listViewDir': {
controller: function ($scope) {
$scope.ButtonClicked = function(){
alert('Button wurde geklickt!');
};
return $scope;
},
link: function (scope, element, attrs){
var template = '<button ng-click="ButtonClicked()" > Alert</button>';
element.html(template);
$compile(element.contents())(scope);
}
}
};
return {
get: get
};
////////////////////////
function get(key){
return configurations[key];
}
});
app.controller('MainCtrl', function($scope, directiveConfigurations) {
$scope.config = directiveConfigurations.get('listViewDir');
});
app.directive("listViewDir", function(){
return {
restrict: "E",
scope: {
datasource: '=',
config: '='
},
controller: function ($scope) {
return $scope.config.controller($scope);
},
link: function(scope, element, attrs){
return scope.config.link(scope, element, attrs);
}
};
});
I've got a simple angular app, and I'm trying to inject some html into the page using ngBindHtml. However, it's not being injected. Here's my HTML:
<main id="main" ng-bind-html="oreGen | trust"></main>
And here's my angular app:
angular.module('programApp', ['programApp.controllers','programApp.filters','ngSanitize']);
angular.module('programApp.controllers', [])
.controller('programController', ['$scope', '$filter', function($scope, $filter){
$scope.oreGen = '<div class="oreFunction" ng-click="collectFunction(\'parenthesis\', 1)">test text</div>';
$scope.collectFunction = function(value1, value2){
alert(value1 + value2);
};
}]);
angular.module('programApp.filters', []).filter('trust', ['$sce', function($sce){
return function(text) {
return $sce.trustAsHtml(text);
};
}]);
When the page is loaded, nothing appears inside the main element.
Here's a codepen: http://codepen.io/trueScript/pen/MwbVpO?editors=101
You can see the div being ngBinded does not appear. Why is this?
You can use a directive instead a filter. Please look at this JSFiddle
HTML:
<div ng-app="myApp" ng-controller="programController">
<dir id="main" content="oreGen"></dir>
</div>
JS:
angular.module('myApp', [])
.controller('programController', ['$scope', '$filter', function ($scope, $filter) {
$scope.oreGen = '<dir class="oreFunction" ng-click="collectFunction(\'parenthesis\', 1)">test text</dir>';
$scope.collectFunction = function (value1, value2) {
alert(value1 + value2);
};
}])
.directive('dir', function ($compile, $parse) {
return {
restrict: 'E',
link: function (scope, element, attr) {
scope.$watch(attr.content, function () {
element.html($parse(attr.content)(scope));
$compile(element.contents())(scope);
}, true);
}
}
});
Trying to do some DOM manipulation, but link() is never called so nothing happens:
app.js
var app = angular.module('app', ['directives', ...]);
var directives = angular.module('directives', []);
...
directives.js
directives.directive('doIt', ['$window', function($window) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
console.log('Inside link()');
// Do stuff with $window
}
};
]});
HTML
<html ng-app="app">
<body>
<div ng-view>
<div do-it>
// ....
</div>
</div>
</body>
</html>
What am I missing?
Your square bracket is incorrect
directives.directive('doIt', ['$window', function($window) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
console.log('Inside link()');
// Do stuff with $window
}
};
}]);//Check this part. The square bracket was on the wrong side of }
Move it like like I have it above
You also have some extra periods in your module decleration
var app = angular.module('app', ['directives']); //remove the extra ....'s
is this plnkr help?plnkr
angular.module('app', [])
// .controller('Controller', ['$scope', function($scope) {
// $scope.customer = {
// name: 'Naomi',
// address: '1600 Amphitheatre'
// };
// }])
.directive('doIt', ['$window', function($window) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
console.log('Inside link()');
// Do stuff with $window
}
};
}]);
I have a directive in which controller exists, where i have a function. I need to call that function from another controller.
Directive :
angular.module('test.directives').directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
$scope.getRoles = function() {
console.log('hi');
};
}
};
});
$scope.getRoles method is the method i need to call from different controller.
Controller:
angular.module("test.controllers").controller("testController", function($scope, $http) {
$scope.getUsers = function() {
// i need to call getRoles method here
}
});
How can i do that?
Please help,
Thanks.
You can use AngularJS Service/Factory
I put the getRoles function within the factory for the API which can be injected anywhere.
Working Demo
var RolesModule = angular.module('UserRoles', []);
RolesModule.factory('RolesAPI', function() {
return {
getRoles: function() {
this.roles = 'my roles';
console.log('test');
}
}
});
angular.module("test.controllers",['UserRoles'])
.controller("testController",function($scope,$rootScope,RolesAPI, $http) {
$scope.getUsers = function() {
RolesAPI.getRoles();
}
});
angular.module('test.directives',['UserRoles'])
.directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
}
};
})
Try following
angular.module('test.directives').directive("manageAccess", function() {
return {
restrict: "E",
replace: true,
scope: {getRoles: '='},
templateUrl: "template/test.html",
controller: function($scope, $element, $http) {
$scope.getRoles = function() {
console.log('hi');
};
}
};
});
controller
angular.module("test.controllers").controller("testController", function($scope, $http) {
$scope.getUsers = function() {
// i need to call getRoles method here
$scope.getRoles()
}
});
in html
<manage-access get-roles="getRoles"></manage-access>
If the function is not dependent on the directive elements, move that to a service pass it to both directive and the testcontroller.