Implementing a dynamic view-stack in angular: Right approach?

498 views
Skip to first unread message

Daniel Platz

unread,
Jul 12, 2013, 6:47:56 AM7/12/13
to ang...@googlegroups.com
Hi tere,
I am trying to build a service + directive to allow for something like a ng-view facility that is not routing-based but configured via explicit calls to a service.
I.e. something like a "show" call with paramters 1.) Name of a template to use, 2.) name of a controller to use and 3.) a set of properties to initialize/customize the controller with.
So, basically to a call
viewStack.pushView("ViewCtrl", "viewTemplate.html", { /* some props to initialize the ViewCtrl */});
that then injects the template with that particular controller and calls a init-function on that controller where the third argument is give as a parameter to this init-method.

Additionally, I want it later to be like logical stack of views where I can push and pop view from and to. Visually, this might then be augment by some fadeIn/out animations.
I haven't really implemented that part yet, but thats the final goal, in case you are wondering why i use the naming "Push" and "pop". Not sure yet, but i guess i will have to keep track of the scopeson the stack and bind/unbind them based on the current view/template shown.

Now to my actual question: As I am quiet new to angular and it was really hard for me to get this working (in my head), i.e. creating the controler manually and binding it to a scope; and also using a service as the interface that communications to the directive (see my code below): Is this good design? should I have done differently?
Still struggeling a little to get this view-stack implemented with the concepts of angular...

Any comments/hints are very welcome.

Thanks,
Daniel

app.controller('TestCtrl', function($scope, viewStack) {
    $scope.push = function() {
        viewStack.pushView("ViewCtrl", "viewTemplate.html", { /* some props to initialize the ViewCtrl */});
    }
});


app.controller('ViewCtrl', function($scope) {
    this.init = function(props) {
        // set up scope based on props here
    }
});

app.factory("viewStack", function($templateCache, $document, $compile, $rootScope) {
    var stack = [];

    return {
        pushView: function(viewCtrl, template, props) {
            $rootScope.$emit('showView', { 'controller': viewCtrl, 'template': template, 'props': props});
        },

        popView: function() {
            // todo
        }
    };
});

app.directive('viewContainer', function factory($rootScope, $compile, $controller, $http, $templateCache) {
    return {
        restrict: 'A',
        template: '<div style="position: absolute; width: 200px; height: 200px; z-index: 1; background-color: red;"></div>',
       
        link: function($scope, $element, $attrs) {
            console.log("link");
             $rootScope.$on('showView',function(event, props) {
                $http.get(props.template, {cache: $templateCache}).success(function(response) {

                    var ctrl = $controller(props.controller, { '$scope': $scope });
                    ctrl.init(props.props);

                    $element.html(response);
                    $compile($element.contents())($scope);

                }).error(function() {
                    console.log("error");
                });
             });
        }
    };
});


<div view-container></div>
<button ng-controller="TestCtrl" ng-click="push()">

ganaraj p r

unread,
Jul 12, 2013, 7:06:48 AM7/12/13
to ang...@googlegroups.com
HI Daniel,

Consider this my view and not the view of the whole angularjs community.

I have a strong feeling you are doing something the wrong way. AngularJS uses DOM based templating. It isnt string based templating. In string based templating composition happens by concatenating strings together and finally shoving that concatenated string into the DOM using innerHtml or something like that.

In DOM based templating, you do the opposite. You already define in your DOM ( through html! ) a complete set of all the operations that can happen on the DOM. Angular, runs through this DOM, removing the nodes that dont relate to the current state (model!). 

Having said this, I am not saying that compiling strings on the fly and pushing them into the DOM is totally wrong. But, you should be only doing this if you are absolutely certain as to why you are doing this. You should have very strong reasoning to back up your choice. If you are doing this, then its unnatural to what angular is meant for. 

Hope this helps you.     



--
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 angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Regards,
Ganaraj P R

Daniel Platz

unread,
Jul 12, 2013, 8:18:09 AM7/12/13
to ang...@googlegroups.com
Hi Ganaraj,
Thanks for your comment. I value any reponse that sheds some additional view on angular and helps me to understand what really makes up the philosophy behind it.
Having said that, i think ng-include for templates and ng-view, for showing a template based on a route, is not so much different from what I am doing.
I totally get what you are saying and would also like to rather go a DOM-based approach but it just seems not viable if you have a very dynamic application that has a lot of different dialos shown to the user. You don't want to define all of them in one big html page that you dynamically set visible/hide.

If there are any more views on this and my using events to communicate from a service to a directive or the overall approach, please let me know.

Cheers,
Daniel

Matej Svejda

unread,
Sep 6, 2013, 1:36:25 PM9/6/13
to ang...@googlegroups.com
Hello Daniel,

I too am looking into a push/pop views implementation for angular js, as I am writing an application for mobile devices and this seems to be the best aproach. I would like to have something like the view stack for iOS. Have you made any progress on your implementation?

Cheers and many thanks,
Matej
Reply all
Reply to author
Forward
0 new messages