Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add Angular-enabled elements to DOM?

I would like to add some Angular-enabled DOM elements programmatically. Actually, I probably will need to add custom components. How can I do it?

Here's a trivial fiddle to demonstrate the issue: http://jsfiddle.net/ZJSz4/2/

HTML:

<div ng-app="main">
    <div ng-controller="MyCtrl">
        <button ng-click="add()" >Add</button>
        <div id="container">
            <div>{{test}}</div>
        </div>
    </div>
</div>

JS:

angular.module("main", []).controller("MyCtrl", function($scope) {
    $scope.add = function() {
        $("#container").append("<div>{{test}}</div>");
    };

    $scope.test = 'Test Message';
});

Just in case, I expect it to add a div showing "Test Message" for each click - not {{test}}.

Why do I need it? Well, I would like to have a few sortable columns (in jQuery sortable sense) with portlets. I imagine each portlet could be a component.

Am I climbing the wrong hill? What is the Angular way to solve this?

EDIT: I hoped this simplistic example wouldn't end that way, but anyway. The ultimate goal is not to display a div for each element in an array.

What I really want is a more complex controller. I need a portlet container with some interesting behavior. It may need to decide to place each portlet in a different column. It may offer changing the layout and have a decent way to reorganize portlets in such event. And so on.

like image 622
Konrad Garus Avatar asked Apr 05 '13 20:04

Konrad Garus


1 Answers

Although I am not entirely sure what the desired outcome is, you do want to be sure that all DOM manipulation is done within a directive and not inside your controller.

This JSfiddle example should get you going in the right direction.

http://jsfiddle.net/ZJSz4/5/

<div ng-app="main">
<div ng-controller="MyCtrl">
<div id="container">
    <button ng-click="add()" >Add</button>
    <ng-portlet></ng-portlet>
</div>
</div>

angular.module("main", []).controller("MyCtrl", function($scope) {
    $scope.test = 'Test Message';
}).directive("ngPortlet", function ($compile) {
return {
    template: '<div>{{test}}</div>   ',
    restrict: 'E',
    link: function (scope, elm) {
        scope.add = function(){
            console.log(elm);
           elm.after($compile('<ng-portlet></ng-portlet>')(scope));
        }
    }
};
});
like image 172
Jonathan Palumbo Avatar answered Sep 21 '22 15:09

Jonathan Palumbo