Jay
Jay

Reputation: 73

rendering html from a controller in angular

Hopefully someone can point my in the right direction.

I am building a web app and part of it requires a user to click a button as fast as they can to obtain a score. The design dictates that I will need to show this score in double digits i.e 9 would be 09 so for styling I need to wrap span tags around each digit.

I have got everything working as required, I'm just having an issue with outputting the score that is wrapped in span tags as rendered html in my view.

I've put together a fiddle for the section that is causing me problems. Any advice, help, best practices etc is much appreciated.

What I've tried:

I've included a few of the things I've tried. Basically they involve using $sce and trying to ng-bind-html in the view. Attempt 3 seems the most logical to me but the $scope.count isn't being updated. I'm guessing I need to add a $watch or $apply function to keep it binded? but I'm not too sure how to implement it or even if this is good practice. Also, because I'm outputting html is it better practice to do this in a directive?

Fiddle http://jsfiddle.net/funkycamel/gvxpnvqp/4/

HTML

<section ng-app="myApp">
<div ng-controller="MyController">

    <button ng-click="add(1)">add</button>

    <!-- First attempt -->
    <p class="first-attempt">{{ pad(count) }}</p>

    <!-- Second attempt -->
    <!-- in order for this attempt to work I have to call the pad2 function which
    returns trustedHtml -->
    {{ pad2(count) }}
    <p class="second-attempt" ng-bind-html="trustedHtml"></p>

    <!-- Third attempt -->
    <p class="third-attempt" ng-bind-html="moreTrustedHtml"></p>

</div>

Javascript

var app = angular.module('myApp', []);
app.controller('MyController', ['$scope', '$sce', function ($scope, $sce) {

// Set initial count to 0
$scope.count = 0;

// function to add to $scope.count
$scope.add = function (amount) {
    $scope.count += amount;
};

// Attempt 1
// make sure number displays as a double digit if
// under 10. convert to string to add span tags
$scope.pad = function (number) {
    var input = (number < 10 ? '0' : '') + number;
    var n = input.toString();
    var j = n.split('');
    var newText = '';
    var trustedHtml = '';

    for (var i = 0; i < n.length; i++) {
        newText += '<span>' + n[i] + '</span>';
    }

    return newText;
};


// Attempt 2 - trying to sanitise output
// same as above just returning trusted html
$scope.pad2 = function (number) {
    var input = (number < 10 ? '0' : '') + number;
    var n = input.toString();
    var j = n.split('');
    var newText = '';
    var trustedHtml = '';

    for (var i = 0; i < n.length; i++) {
        newText += '<span>' + n[i] + '</span>';
    }

    // return sanitised text, hopefully
    $scope.trustedHtml = $sce.trustAsHtml(newText);
    return $scope.trustedHtml;
};

// Attempt 3
// Trying to sanitise the count variable
$scope.moreTrustedHtml = $sce.trustAsHtml($scope.pad($scope.count));

}]);

These currently output

<span>0</span><span>0</span>

<span>0</span><span>0</span>

00
00

Again any advice/help is greatly appreciated.

Upvotes: 1

Views: 1697

Answers (1)

charlietfl
charlietfl

Reputation: 171669

Far simpler solution:

HTML

<p>{{ count < 10 ? '0' + count : count}}</p>

Controller:

app.controller('MyController', ['$scope', function ($scope) {
    $scope.count = 0;

    $scope.add = function (amount) {
        $scope.count += amount;
    };
}]);

DEMO

If you prefer you can do the padding in the controller instead, just use another variable

app.controller('MyController', ['$scope', function ($scope) {
    var count = 0;
    $scope.countText = '0';

    $scope.add = function (amount) {
        count += amount;
        $scope.countText = count < 10 ? '0' + count : count;
    };
}]);

Upvotes: 1

Related Questions