[AngularJs 1.4, TypeScript 1.5, Angular-Material 0.9.7]
I'm developing an application where I want to display ~100+ rows in an
ng-repeat (perhaps an infinite scrolling list). Each row features ~10
fields of different types of metadata : text, date, boolean, .. I was
thinking of constructing the table like this:
<table>
<tr ng-repeat="node in nodes">
<td><meta-data node="node" property="property1" raw></meta-data></td>
<td><meta-data node="node" property="property2" format="dd MM yyyy"
></meta-data></td>
</tr>
</table>
Where meta-data would be my custom directive. The directive resolves the
value to display by searching the value corresponding to propertyX in the
node object (containing a list of key-value pairs for each property).
'Format' and 'raw' represent several arguments that will influence the
template I'll use to display the value.
angular.module('myModule')
.directive('metaData',() => { return {
restrict: 'E',
controller: 'DataController',
controllerAs: 'dc',
scope: true,
bindToController: {
node: '=',
property: '=',
raw: '=',
format: '='
},
templateUrl: resolveTemplate(type)
}
The first issue I'm having is that I want to show a different template for
each type of data. The directive's DataController can resolve the type
based on the property supplied using an asynchronous dictionary call.
Ideally each type of data is represented in a different directive (e.g.
<meta-data-date> for date format) for full functionality.
The problem I'm having is that the resolveTemplate() function doesn't know
the type at the point it's required. First of all I don't have the data
available at the point the directive is being rendered since that would
require resolving an asynchronous database call before rendering the
directive. And secondly I can't seem to provide any arguments from the
directive for resolveTemplate(), since the data binding hasn't been
finalized at the point this function is called.
Alternative solutions would exist of replacing the resolveTemplate function
with a huge template consisting of each type of custom directive in a large
ng-if tree that evaluates once the Promise of the dictionary call is
resolved, killing all performance (especially on IE.. ugh).
Or maybe have <meta-data> resolve the value and promise, which then calls a
second directive to resolve the template, which then finally implements the
actual directive that contains the appropriate template for representing a
value of a certain type. Issues with this is that I still won't be able to
resolve the type in the second directive using a resolveTemplate()
function, that I don't know how I will pass on a list of optional arguments
and that I'll be nesting three directives - probably killing off
performance again!
<meta-data node="node" property="property2" format="dd MM yyyy"> //
directive 1 : resolve value and type
<meta-data-type value="value" type="type" args="args"> //
directive 2 : resolve type-based directive
<meta-data-date value="value" args="args"> //
directive 3 : knows how to display value of a specific type
{{value | date : format}} //
custom template for type, based on optional arguments
</meta-data-date>
</meta-data-type>
</meta-data>
I'm really at a loss here where I feel I don't know enough about custom
directives to come up with an elegant solution for my problem. Both
handling the asynchronous dictionary call and providing the appropriate
template based on a type value made my head spin for the last few days.
PS : I was also wondering what would be the most performant way of passing
down variables using directives. Is one-way('@') binding more performant
than two-way binding ('=') if the directive will just display and not alter
a varialbe? Or are there better ways?
--
You received this message because you are subscribed to the Google Groups
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.