Multiple Views sync / One Model Two Controllers.

3,127 views
Skip to first unread message

ganaraj p r

unread,
Apr 22, 2012, 11:34:13 AM4/22/12
to ang...@googlegroups.com
Hi,

Pretty new to Angular and quite excited about it. My question is related to one of the older posts.i.e about having different controllers sharing a single model. Basically what I want to achieve is a screen showing two views of the same model. 

Suppose you maintain a model which contains width and height. If I want to show two views simultaneously for the same model. One view is actually a drawn rectangle which shows the width, height etc visually. The other view is something like a text view, with input fields bound to this model. Changing the Input fields -> change model -> change the other view.

Now since these 2 views are going to grow big ( in terms of behaviour ), it would be better for organization to put them into 2 different controllers! I want to share the same model between the 2. So this is what I am doing for it.

<!doctype html>
<html ng-app>
<head>
    <script type="text/javascript">

        var master = {width:200,height:100};

        function AlbumCtrl($scope)
        {
            $scope.master = master;
            $scope.mystyle = { display:"block", "background-color" : "#333333", width : master.width + 'px', height: master.height + 'px'  };
        }

        function EditCtrl($scope)
        {
            $scope.master = master;

        }
    </script>
    <!-- Le styles -->
    <link href="assets/css/bootstrap.css" rel="stylesheet">
    <link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
    <link href="assets/css/docs.css" rel="stylesheet">
    <link href="assets/js/google-code-prettify/prettify.css" rel="stylesheet">

    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
    <![endif]-->

    <!-- Le fav and touch icons -->
    <link rel="shortcut icon" href="assets/ico/favicon.ico">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/ico/apple-touch-icon-114-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/ico/apple-touch-icon-72-precomposed.png">
    <link rel="apple-touch-icon-precomposed" href="assets/ico/apple-touch-icon-57-precomposed.png">
</head>
<body>
<div style="position:relative;display: block;width: auto; height: 300px; background-color: #CCC;" ng-controller="AlbumCtrl">
    <div ng-style="mystyle"></div>
</div>
<div ng-controller="EditCtrl">
    <form class="form-horizontal">
        Width : <input type="text" ng-model="master.width">
        Height : <input type="text" ng-model="master.height">
    </form>
</div>
</body>
</html>



Everything works except for the style not getting updated. Can someone point to me what I am doing wrong here? Or should this be achieved differently ?

--
Regards,
Ganaraj P R

Peter Bacon Darwin

unread,
Apr 22, 2012, 12:46:14 PM4/22/12
to ang...@googlegroups.com
It is probably best to put the shared data in a Service but alternatively you can put it in a parent scope to the two controllers.  The easiest way to do this is to associate a new controller with an element of the HTML that wraps the other two controller elements.  Here is a Fiddle : http://tinkerbin.com/VVJvxFmN (playing with an alternative to JsFiddle)
By the way, Angular isn't able to work out that myStyle relies upon master.width and master.height so it is not triggering the update on it.  I could get the style to update by creating my own watch on those two elements.  You could simplify this by using a deep watch: http://tinkerbin.com/JbGovm4n.  Also, it is a good idea to setup your own watch as you may want to do something special on an invalid value for width or height.
Regards,
Pete


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/angular?hl=en.

ganaraj p r

unread,
Apr 22, 2012, 3:27:31 PM4/22/12
to ang...@googlegroups.com
Thank you, that was somewhat helpful, though I dont know whether something was wrong with how I was viewing it or something else, I dint get either of your fiddles to work. 

I tinkered with it a bit more and got it to work. Here is the fiddle.



So, here is my follow up question. I have heard quite a few arguments that one should be using a Service if we are using shared data. Can someone explain to me why that would be a better way of doing stuff? What would be the possible pitfalls of using an object as I have done? 

Also, if you see the fiddle I have attached, I am also interested in editing the content in one of the views. If I use a service would that be possible? I guess I can create a new directive called a box which will do exactly what I want there and use "boxes" instead of div's in the html. Going to try that next. 

Peter Bacon Darwin

unread,
Apr 22, 2012, 3:37:15 PM4/22/12
to ang...@googlegroups.com
My fiddles work for me.  I am running Chrome in Ubuntu.  I guess you pressed Run?
The thing about using the closure as you have done here is that you don't have much room for decoupling the controllers from each other.  Angular makes it really easy to modularise your code (they even put everything in modules for a start).  A service is basically a singleton object that can be injected into controllers or other services as you request.  It hides the implementation of the data source and allows you to plug in alternate implementations without changing the controller code.
How do you see your fiddle evolving into the full blown application?  Where will you get this master data from and what will you do with it once the use has changed it?
Pete

ganaraj p r

unread,
Apr 22, 2012, 3:51:47 PM4/22/12
to ang...@googlegroups.com
Sorry my bad :)

Dint know I had to press Run... Feel like an idiot!.

About the service. That seems interesting. Dint know that it was a singleton object. Well, I am building an app that allows the user to draw boxes. So that they get a visual representation of what they are going to put up on the screen. After the user finishes doing this ( after creating multiple boxes perhaps! )... I need to generate a corresponding xml which represents the users drawing ( in our own custom xml ).. Something like 

<element type="text" width="100" height="200" left="0" top="0" ...../>

And there is a hierarchy of this xml.This particular node would be somewhere in the 4th or 5th child from the root. 

So the user draws these boxes ( in view 1 )... in view 2 the properties of the element will be shown... and once the editing is done.. generate the correspoding xml for each element.  

Peter Bacon Darwin

unread,
Apr 22, 2012, 4:29:02 PM4/22/12
to ang...@googlegroups.com
So given your situation, I would personally use a service and put all the functionality that converts the model into the xml inside that (i.e. a save method).  Then it is nicely encapsulated (in case it changes later) and your controllers can just forget about it and just call save when ready.
Pete
Reply all
Reply to author
Forward
0 new messages