Angular Directive param value array - angularjs

How can I use an array which is given as an attribute of a directive in the linker of the directive
[
{
"state": "bootstrap.formwizard.ethernet",
"placeHolder": "lNetworkConfWizardMenu",
"stepNumber": 1,
"next": "bootstrap.formwizard.datetime"
},
{
"state": "bootstrap.formwizard.datetime",
"placeHolder": "lDateSetWizardMenu",
"previous": "bootstrap.formwizard.ethernet",
"stepNumber": 2,
"next": "bootstrap.formwizard.countrysetting"
},
]
Template
<formprogressbar steps="wizardSteps" />
Directive
angular.module('smaModules.formProgressbar', [])
.directive('formprogressbar', function ($log) {
function linker(scope, element, attrs) {
console.log(scope);
test = attrs.steps[0]
console.log(test);
}
return {
restrict: 'E',
scope: {
steps: '='
},
template: 'Steps: {{ steps[0] }}',
link: linker
};
});
In the template I have access but not in the linker function. What's wrong?

You want to access the steps off of your scope for it to be the same as in your template. Also you should declare your variable for best practice.
.directive('formprogressbar', function ($log, $filter) {
function linker(scope, element, attrs) {
console.log(scope);
var test = scope.steps[0];
console.log(test);
}
return {
restrict: 'E',
scope: {
steps: '='
},
template: 'Steps: {{ steps[0] }}',
link: linker
};
});
attrs.steps[0] was probably giving you the result of 'w', this is because attrs.steps is the string "wizardSteps", the first index of the string being 'w'.

Related

Why it not working? following angularjs Example

Here i created some Example.. In this Example 1 I put directly
//{{arr.Description}}
like this its working but via directive its not working what misstake i did
can please explain me?
Thanks friends
var app = angular.module('components', []);
app.directive('subpane', function() {
return {
restrict: 'E',
scope: {
array: '#'
},
template:'<li ng-repeat="arr in array">{{arr.Description}}</li>',
link: function(scope) {
}
};
})
app.controller('tabController', ['$scope', function ($scope) {
$scope.array =[{
"title": 0,
"Description": "Select your option"
},
{
"title": 1,
"Description": "Male"
},
{
"title": 2,
"Description": "Female"
},
{
"title": 3,
"Description": "Unknown"
}];
}])
<script data-require="angular.js#~1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
<body ng-app="components" ng-controller="tabController">
<span>Example 1 Working fine</span>
<li ng-repeat="arr in array">{{arr.Description}}</li>
<span>Example 2 Not Working.. Here also same thing only i did via directive.. why this is not working?</span>
<subpane array={{array}}></subpane>
</body>
Use '=' for the scope param and remove '{{}}' in the markup.
var app = angular.module('components', []);
app.directive('subpane', function() {
return {
restrict: 'E',
scope: {
array: '='
},
template:'<li ng-repeat="arr in array">{{arr.Description}}</li>',
link: function(scope) {
}
};
})
app.controller('tabController', ['$scope', function ($scope) {
$scope.array =[{
"title": 0,
"Description": "Select your option"
},
{
"title": 1,
"Description": "Male"
},
{
"title": 2,
"Description": "Female"
},
{
"title": 3,
"Description": "Unknown"
}];
}])
<script data-require="angular.js#~1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
<body ng-app="components" ng-controller="tabController">
<span>Example 1 Working fine</span>
<li ng-repeat="arr in array">{{arr.Description}}</li>
<span>Example 2 Not Working.. Here also same thing only i did via directive.. why this is not working?</span>
<subpane array=array></subpane>
</body>
You need to add "plain: true" in the directive if you don't use templateUrl
app.directive('subpane', function() {
return {
restrict: 'E',
scope: {
array: '=' // = not #, = is for object/array ; = is for text/number.
},
template:'<li ng-repeat="arr in array">{{arr.Description}}</li>',
plain: true,
link: function(scope) {
}
};
})
In the html dont put {{ }} in the parameter array
<subpane array="array"></subpane>
camden_kid has posted an acceptable answer but not probably the best one. In your template:
<subpane array={{array}}></subpane>
Must have the quotes:
<subpane array="{{array}}"></subpane>
Please also note that camden_kid suggested to change
scope: {
array: '#'
}
To
scope: {
array: '='
}
This is what is needed for double binding and it is only necessary if you have to edit in any way the original value (in the parent scope) from within the directive's isolated scope.
You probably should read more carefully the docs: https://docs.angularjs.org/guide/directive

Using directives in angularjs with templateUrl

I wrote a code with angularjs that uses a directive to bring a list of categories from show-category.html file and show them on the index page, I did everything as I've learned but still can't get the categories to be displayed when index.html is loaded.
inside app.js file
app.directive('showCategories', function() {
return {
restrict: 'E',
templateUrl: 'show-categories.html'
};
});
you can see the full code on plunker here:
http://plnkr.co/edit/FSsNAq?p=preview
You placed your directive definition right in the middle of the controller, take it outside and it works (barring some other non-existing functions you have there):
app.controller("BookCtrl", function($scope) {
$scope.categories = [{
"id": 0,
"name": "Type"
}, {
"id": 1,
"name": "Date"
}, {
"id": 1,
"name": "Name"
}
];
...
});
app.directive('showCategories', function() {
return {
restrict: 'E',
templateUrl: 'show-categories.html'
};
});
Plunker

Bind JSON data into Morris linechart Directive using AngularJs Services

I am trying to show linechart by using webapi. Static data showing successfully but when I trying to bind JSON data array by calling services it not showing .
When I binding static data into chart_options.data its working fine.
What I doing wrong here ?
mycontroller.js
myApp.controller('connectionSummaryController', function ($scope, connectionService) {
$scope.chart_options = {
data:[],
xkey: 'RegistedDay',
ykeys: ['SubsriberRegisted'],
labels: ['SubsriberRegisted'],
parseTime: false
};
connectionService.getSubscriberLastWeek()
.then(function (resp) {
//dumy data (we will call services here and will bind data into chart_options.data )
$scope.chart_options.data = [{
"RegistedDay": "Monday",
"SubsriberRegisted": 500
}, {
"RegistedDay": "Tuesday",
"SubsriberRegisted": 24
}, {
"RegistedDay": "III",
"SubsriberRegisted": 3
}, {
"RegistedDay": "IV",
"SubsriberRegisted": 12
}, {
"RegistedDay": "V",
"SubsriberRegisted": 13
}, {
"RegistedDay": "VI",
"SubsriberRegisted": 22
}, {
"RegistedDay": "VII",
"SubsriberRegisted": 5
}];
})
;
linechart.js
myapp.directive('linechart', function () {
function createChart(el_id, options) {
console.log(options);
options.element = el_id;
var r = new Morris.Line(options);
return r;
}
return {
restrict: 'E',
scope: {
options: '='
},
replace: true,
template: '<div></div>',
link: function (scope, element, attrs) {
return createChart(attrs.id, scope.options)
}
}
})
myservice.js
myApp.service("connectionService", function myfunction($http) {
this.getSubscriberLastWeek = function (Id) {
return $http({
method: 'GET',
url: baseURL + 'Api/Connect/SubscriberLastWeek/1'
});
};
});

scope of event arguments in angular directive

I have the following angular app to create a menu of sections/products.
at present when rendered and hitting the 'add' button that is rendered within each li I want to add a section/product as a sub of that section however multiple new children are created.
ultimately I wish to display a form which when submitted will create the child but that is the next step. Right now I need to limit the scope to the current section and not have multiple bound clicks.
If you need more information please state and I will post in an edit.
Some sample data data.
{
"sections":[
{
"name":"Flags",
"sections":[
{
"name":"Europe",
"sections":[],
"products":[
{ "name": "France" },
{ "name": "Germany" },
{ "name": "Ireland" },
{ "name": "England" }
]
},
{
"name": "Africa",
"sections":[],
"products":[
{ "name": "Egypt" },
{ "name": "Nigeria" },
{ "name": "Chad" }
]
},
{
"name": "South America",
"sections":[],
"products": [
{ "name": "Brasil" },
{ "name": "Argentina" },
{ "name": "Peru" }
]
}
],
"products":[]
},
{
"name": "Maps",
"sections":[
{
"name": "Africa",
"sections":[],
"products":[
{ "name": "Egypt" },
{ "name": "Nigeria" },
{ "name": "Chad" }
]
},
{
"name": "South America",
"sections":[],
"products": [
{ "name": "Brasil" },
{ "name": "Argentina" },
{ "name": "Peru" }
]
}
],
"products":[]
}
],
"products":[]
}
The app.
'use strict';
var menuApp = angular.module('menuApp', []);
menuApp
.directive('sections', function () {
return {
restrict: "E",
replace: true,
scope: {
sections: '='
},
template: '<ul><section ng-repeat="section in sections" section="section" /></ul>'
};
})
.directive('section', function ($compile) {
return {
restrict: "E",
replace: true,
scope: {
section: '=section'
},
template: '<li class="section">{{section.name}} <button ng-click="addSub(section)">Add</button></li>',
link: function (scope, element, attrs, controller) {
if (angular.isArray(scope.section.sections)) {
element.append("<sections sections='section.sections'></sections>");
$compile(element.contents())(scope);
}
if(angular.isArray(scope.section.products)){
element.append("<products products='section.products'></products>");
$compile(element.contents())(scope);
};
},
controller : function($scope){
console.log($scope);
$scope.addSub = function (section){
//console.log(section,'Adding Sub');
section.sections.push({"name":"Section","sections":[],"products":[]});
};
}
};
})
.directive('products', function () {
return {
restrict: "E",
replace: true,
scope: {
products: '='
},
template: '<ul><product ng-repeat="product in products" product="product"></product></ul>'
};
})
.directive('product', function ($compile) {
return {
restrict: "E",
replace: true,
scope: {
product: '='
},
template: '<li class="product">{{product.name}}</li>'
};
});
menuApp.controller('menuCtrl', function menuCtrl($scope,$http) {
$http.get('/ajax/getvenuesmenu?venueID='+venueMenu.venueId).success(function(resp) {
$scope.sections = resp;
});
$scope.add = function(data){
data.push({"name":"Section","sections":[]});
};
});
Took me a bit to figure it out but here's the basic problem, you are compiling the full contents of section 2 extra times and each compile seems to add a new event handler.
Instead of compiling the contents of element each time you make an append of new template, compile the template itself (outside of the DOM) and then append the compiled template. This way the ng-click handler doesn't get compiled again other than initial scope creation
Here's an abbreviated version with one template appended:
link: function (scope, element, attrs, controller) {
if (angular.isArray(scope.section.sections)) {
/* compile outside of the DOM*/
var subsections = $compile("<sections sections='section.sections'></sections>")(scope);
/* append compilation*/
element.append(subsections);
}
DEMO
Another approach would be to create a complete template string in link by checking for subsections and products, then compiling everything all at once....instead of using template option
Code for alternate approach compiling complete section at once:
.directive('section', function ($compile, $timeout) {
return {
restrict: "E",
scope: {
section: '=section'
},
link: function (scope, element, attrs, controller) {
var template = '<li class="section">{{section.name}} <button ng-click="addSub(section)">Add</button>';
if (angular.isArray(scope.section.sections)) {
template += "<sections sections='section.sections'></sections>";
}
if (angular.isArray(scope.section.products)) {
template += "<products products='section.products'></products>";
};
template += '</li>';
var compiledTemplate = $compile(template)(scope);
element.replaceWith(compiledTemplate);
scope.addSub = function (section) {
section.sections.push({ "name": "Section", "sections": [], "products": []
});
};
}
};
})
DEMO-Alt

How to use jsTree events with AngularJS

I load my tree successfully using a directive in AngularJS.Now i want to add events (here select node) in my tree, so i did like this. but i can't see my alert .
My code:
app.directive('jstree', function() {
return {
restrict: 'A',
scope: {
jstree: '='
},
link: function(scope, element, attrs)
{
scope.$watch('jstree', function()
{
$(element).jstree({
"json_data" :{
"data":scope.jstree.data
},
"themes" : {
"theme" : "classic",
"dots" : true,
"icons" : true
},
"plugins" : [ "themes", "json_data" ]
}, false);
}, true);
// select a node
element.bind("select_node.jstree",function(e, data) {
$window.alert(e.data);
});
}
};
});
Any idea were i went wrong ?
To use events in jstree, you have to add "ui" in this line :
"plugins" : [ "themes", "json_data", "ui" ]
Now it works.
Looking at the jstree demo, you'll want to call bind on the jstree object, not on the element (you'll be able to bind to click on the element, but this probably isn't what you want)
$(element)
.jstree({
"json_data" : {
"data" : scope.jstree.data
},
"themes" : {
"theme" : "classic",
"dots" : true,
"icons" : true
},
"plugins" : ["themes", "json_data"]
}, false)
.bind('select_node.jstree', function(ev,data) {
console.log('clicked');
});

Resources