Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the same controller on different elements to refer to the same object

Tags:

angularjs

I figured if I slapped ng-controller="GeneralInfoCtrl" on multiple elements in my DOM they would share the same $scope (or least two-way binding isn't working).

The reason I want to do this is because I have different read-only views with associated modal dialogs in very different parts of the HTML and they don't share a common ancestor (aside from <body> and <html>).

Is there a way to make both controllers refer to the same object/make data binding work between them?


Here's some code for those who insist on seeing markup, written in Jade:

   .client-box(ng-controller="GeneralInfoCtrl")
        .box-header
            .box-title
                h5 General Information
            .box-buttons
                button.btn.btn-small(data-target='#editGeneralInfo', data-toggle='modal', data-backdrop='static') <i class="icon-pencil"></i> Edit
        .box-body
            table.table.table-tight.table-key-value
                tr
                    th Name
                    td {{client.fullName()}}
                tr
                    th Also Known As
                    td {{client.aka}}
                tr
                    th Birth Date
                    td {{client.birthDate|date:'mediumDate'}}
    ...

#editGeneralInfo.modal.hide.fade(ng-controller="GeneralInfoCtrl")
    .modal-header
        button.close(type='button', data-dismiss='modal') &times;
        h3 Edit General Information
    .modal-body
        form.form-horizontal.form-condensed
            .control-group
                label.control-label First Name
                .controls
                    input(type='text', placeholder='First Name', ng-model='client.firstName')
            .control-group
                label.control-label Last Name
                .controls
                    input(type='text', placeholder='Last Name', ng-model='client.lastName')
            .control-group
                label.control-label Also Known As
                .controls
                    input(type='text', placeholder='AKA', ng-model='client.aka')
            .control-group
                label.control-label Birth Date
                .controls
                    input(type='text', placeholder='MM/DD/YYYY', ng-model='client.birthDate')
...

And my controller:

function GeneralInfoCtrl($scope) {
    $scope.client = {
        firstName: 'Charlie',
        lastName: 'Brown',
        birthDate: new Date(2009, 12, 15),
        ...
    }
}
like image 718
mpen Avatar asked Jan 22 '13 07:01

mpen


2 Answers

Each time the Angular compiler finds ng-controller in the HTML, a new scope is created. (If you use ng-view, each time you go to a different route, a new scope is created too.)

If you need to share data between controllers, normally a service is your best option. Put the shared data into the service, and inject the service into the controller:

function GeneralInfoCtrl($scope, MyService) {

Each scope/controller instance will then be able to access the shared data.

Note that services are singletons, so there will only be one instance of your shared data around.

Here is a fiddle (I didn't write it) showing how two controllers can share data.

See also AngularJS: How can I pass variables between controllers? and
Angularjs: two way data bindings and controller reload.

like image 123
Mark Rajcok Avatar answered Nov 13 '22 00:11

Mark Rajcok


Simply put shared data in the root scope, you'll be able to use them everywhere. In Angular $rootScope is the root of all scopes and can be used in controllers to manage data that must be visible across all modules. To use it just inject it in the controller function. For a detailed explanation refer to the Angular developer's guide and to the API doc.

like image 28
remigio Avatar answered Nov 13 '22 00:11

remigio