1

I'm trying to construct a sentence in an AngularJS view. For example, with variables {overdue: 5, name: "Kasper"}, I would like to have "{{overdue}} days overdue. Employee: {{name}}".

I tried using a function:

function renderLine() {
    var results = new Array();
    if (overdue) {
        result.push("{{overdue}} days overdue");
    }
    if (overdue) {
        result.push("{{points}} points");
    }
    /* combine into a string */
    var result = "";
    for (var i = 0; i < results.length; i+=1) {
        if (result.length != 0) {
            result += ", ";
        }
        result += results[i];
    }
    if (result.length > 0) {
        result += ". ";
    }
    /* add name */
    result += "Name: {{name}}";
    return result,
}

More specifically, my question is: how can I use angular directives like {{variable}} in strings that are constructed programmatically and have angular process the directives? I don't want to construct the strings without using directives because the strings are translated into different languages, where the placing of variables within sentences might change.

2 Answers 2

1

I ended up creating an angular directive. The ui-if and ngRepeat directives were good starting points for a DOM-manipulating directive. There is the code for the somewhat modified directive:

angular.module("hk").directive("myDirective", 
[       "$interpolate", "$log",
function($interpolate,   $log) {
    return {
        transclude: 'element',
        replace: false,
        restrict: 'A',
        terminal: true,
        compile: function(tElement, tAttrs, linker) {
            return function(scope, elem, attr) {
                var lastElement;
                var lastScope;
                var expression = attr.myDirective;
                scope.$watch(expression, function (item) {
                    if (lastElement) {
                        lastElement.remove();
                        lastElement = null;
                    }
                    if (lastScope) {
                        lastScope.$destroy();
                        lastScope = null;
                    }
                    lastScope = scope.$new();
                    lastScope.item = item;
                    linker(lastScope, function (clone) {
                        lastElement = clone;
                        var results = [];
                        if (item.isactive) {
                            results.push("++{{item.createdtime | age}} active");
                            if (item.status == 'started') {
                                results.push("++{{item.startedtime | age}} started: {{item.startedby_displayname}}");
                            }
                        }
                        if (item.islate) {
                            results.push("++{{item.latetime | age}} past due");
                        }
                        var result = "";
                        for (var i = 0; i < results.length; i+=1) {
                            if (result.length != 0) {
                                result += ", ";
                            }
                            result += results[i];
                        }
                        if (result.length > 0) {
                            result += ". ";
                        }
                        if (!item.startedby_displayname) {
                            if (item.assignedto_displayname) {
                                result += "++Assigned to {{item.assignedto_displayname}}.";
                            }
                        }
                        var interpolated = $interpolate(result)(lastScope);
                        elem.after(interpolated);
                    });
                });
            };
        }
    };
}]);
Sign up to request clarification or add additional context in comments.

Comments

0

I think you could use $scope.$eval for your purposes. See this fiddle

In you could create a message like this:

$scope.$eval('"Hello "+name');

And then let the string to be evaluated change per language.

{de: '"Hallo " + name', it: '"Buon giorno "+ name', fr: '"Salut " +name'} 

Or something along those lines (of course you'll want to have those translations checked).

You could also create a directive and use $compile to keep the exact strings you have now working.

4 Comments

Thanks, but my solution really requires the use of complete strings with markup.
then you probably need a directive, what you did in your own answer seems a bit over the top though...
Could you give some suggestions how I could simplify my solution?
@KasperRönning I want to create a fiddle for that, but haven't found the time yet...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.