1

I'm currently building an Umbraco dashboard extension using AngularJS and was wondering if there was a means by which I can append HTML to a div on my page.

The idea is that I want to create a sort of history pane that is updated every time a user clicks a button to trigger a web request to our web services. The web request then returns each of the pages that have been updated in Umbraco as well as a link to each page.

So far I have the following:

HTML

<div ng-controller="AxumTailorMade" class="container-fluid">
    <div class="row">
        <div class="col-md-12 heading clearfix">
            <h3>Axum Integration</h3>
            <img class="pull-right" src="/App_Plugins/Axum/css/images/logo.png" />
        </div>
    </div>
    <div class="row">
        <div class="info-window" ng-bind-html="info">

        </div>
        <div class="col-md-3 update-type">
            <h4>Update All Content</h4>
            <p>Synchronise all content changes that have occured in the past 24 hours.</p>
            <span><button class="button button-axum" type="button" ng-disabled="loadAll" ng-click="getAll()">Update</button><img src="/App_Plugins/Axum/css/images/loader.gif" ng-show="loadAll" /></span>
        </div>
   </div>
</div>

My angular controller is as so:

angular.module("umbraco")
    .controller("AxumTailorMade",
    function ($scope, $http, AxumTailorMade, notificationsService) {
        $scope.getAll = function() {
            $scope.loadAll = true;
            $scope.info = "Retreiving updates";
            AxumTailorMade.getAll().success(function (data) {
                if (!data.Result) {
                    $scope.info = null;
                    notificationsService.error("Error", data.Message);
                } else if (data.Result) {
                    $scope.info = "Content updated";
                    notificationsService.success("Success", data.Message);
                }
                $scope.loadAll = false;
            });
        };
    });

I assumed that like jQuery there would be some form of named append function but that doesn't look like that is the case so previously I tried:

$scope.info = $scope.info + "content updated";

But this would return

undefinedcontent updated

So my question is how do I output returned HTML to the info div without deleting the content that is already in there (if there is any).

Any help would be greatly appreciated as this is my first real attempt with Angular.

jezzipin
  • 4,110
  • 14
  • 50
  • 94
  • Generally you should not be appending HTML when using Angular. Instead, use bindings to dynamically produce your output in the view. This post may be relevant to you: [Thinking in AngularJS if I have a jQuery background](http://stackoverflow.com/q/14994391/830125). – Drew Gaynor Feb 05 '15 at 17:30
  • If you look at my code the field is indeed bound however, I don't want the content to be cleared after the next request. Instead, the content should be updated. The methods I am going to be running are completely independent. The documentation you have provided doesn't really help as most of the stuff there I already knew. – jezzipin Feb 05 '15 at 17:34
  • See the answer (http://stackoverflow.com/a/28350683/830125) below and you'll see what I mean. Instead of just appending raw HTML, they are using `ng-repeat`, which is much more in the spirit of Angular and flexible code in general. – Drew Gaynor Feb 05 '15 at 19:35

1 Answers1

3

I think the problem with your earlier attempt is that the $scope.info was undefined the first time you tried to append to it. If it had been initialized with "" or something, I think the simple code you had would have worked:

$scope.info = ""; // don't leave it as undefined
$scope.info = $scope.info + "content updated";

With that said, you should be using an ng-repeat, in my opinion, to list out the messages.

For example, if instead of just appending the string, you could do this in your controller:

$scope.info = []; // empty to start

Then you would add new messages with some controller method:

$scope.addMessage = function(msg) {
    $scope.info.push(msg)
}

Then in your view/HTML, you would use ngRepeat:

<div class="info-window">
    <p ng-repeat="item in info track by $index">{{item}}</p>
</div>

The track by clause allows for duplicate messages.

Update: If the items in $scope.info were actually objects and you wanted to iterate over their properties, which is what I think you ask for in the comment, then you might do something like this. This is getting beyond the scope of the original question, though:

<div class="info-window">
    <p ng-repeat="item in info track by $index">
        <div ng-repeat="(key, value) in item">{{key}} -> {{value}}</div>
    </p>
</div>
Michael Oryl
  • 20,856
  • 14
  • 77
  • 117
  • Okay that's great. However, what if one of my items returned in my Web Service is itself an object such as: Object { 5118="Costa Rica", 5129="Ecuador and Galapagos", 4851="Venezuela"} How would I then loop through these items and output the Key Value pairs? – jezzipin Feb 06 '15 at 12:51
  • 1
    @jezzipin Look at the update in my answer. I hope that's what you were asking. But now you're getting into general use of ng-repeat. There's plenty of documentation on that on the net and here at SO. – Michael Oryl Feb 06 '15 at 14:52
  • Thanks. Figured it out myself an hour ago but thanks for the response. – jezzipin Feb 06 '15 at 14:56