i'm trying create generic directive want use display flexible, spreadsheet-like data entry form.
i'd put data structure & formatting information in html code , have directive take , store in scope later use.
here's sample html i'd use (the information in "field" elements i'd scope):
<array title="breakdown" data="data.breakdown"> <field type="text" default="" name="descr">description</field> <field type="number" default="0" name="price">price</field> <field type="number" default="0" name="tax">tax</field> </array> and directive far
.directive('array', function(){ return { restrict: "e", replace: true, transclude: true, templateurl: "js/array-template.html", compile: function(telement, tattrs, transclude) { var x=transclude(telement); return function(scope, element, attrs) { //the linking function scope.title=attrs.title; } } } } the variable x gives me array of html elements has not "field" elements bunch of empty "span" elements too. work if needed suspect there's simpler way it.
i found solution!
first i've use last example on angularjs website main page: http://angular.github.io/angularjs.org/#/list start rendered html code contained junk because had use ng-transclude directive have <field> elements processed too.
so looked further , found examples of dynamically created templating. gives lot more flexibility , complete rewrite of html without old piece showing in resulting code.
i had use different method of communicating between directives because method used in angularjs website (shared controller) broke down when no ng-transclude used in main directive's template. used added property module object, since both directives belong same object.
here's full code of solution. hope useful people.
html:
<!doctype html> <html> <head> <title></title> <meta http-equiv="content-type" content="text/html; charset=utf-8"> </head> <body ng-app="flexlist"> <array title="breakdown" data="record"> <field type="text" default="" name="descr" title="description"></field> <field type="number" default="0" name="price" title="price"></field> <field type="number" default="0" name="tax" title="tax"></field> </array> <array title="test" data="record"> <field type="text" default="" name="descr" title="description"></field> </array> </body> <script src="js/angular.js"></script> <script src="js/controller.js"></script> </html> javascript ample comments ;-)
function record(){ //a simple constructor provide data table return [{ descr: "example", price: 10, tax: 0.07 }, { descr: "something else", price: 15, tax: 0.11 } ]; } var mod=angular.module('flexlist', []); mod.fields=[]; //container shared between directives //the directive <array> mod.directive('array', function($compile){ //injecting $compile service return { restrict: 'e', //restricted element replace: true, scope:{ title: '@title' //getting title attribute scope }, link: function(scope,element,attr){ //calling function specified in "data" attribute //which should return data filled table scope.source=window[attr.data](); scope.fields=[]; //preparing "field" variable in scope //copying data collected <field> elements scope angular.copy(mod.fields,scope.fields); //preparing collection next use //(in case more 1 <array> block in page mod.fields=[]; newcont=angular.element( //creating template's html '<fieldset>'+ '<legend>{{title}}</legend>'+ '<table border=1>'+ '<tr>'+ '<th ng-repeat="fld in fields">{{fld.title}}</th>'+ '</tr>'+ '<tr ng-repeat="line in source">'+ '<td ng-repeat="fld in fields">{{line[fld.name]}}</td>'+ '</tr>'+ '</table>'+ '</fieldset>'); //applying angular "magic" -- directives in template $compile(newcont)(scope); element.replacewith(newcont); //replace whole <array> element }, controller: function($scope, $attrs){ // nothing here yet } }; }); mod.directive('field',function(){ return { require: '^array', //the "^" means <field> has inside <array> restrict: 'e', //restricted element link: function(scope,element,attrs){ //collecting data element mod.fields.push({ //pushing data collection object type: attrs.type, 'default': attrs['default'], name: attrs.name, title: attrs.title }); } }; });
Comments
Post a Comment