Why do I create the properties in the wrong scope between parent and child controllers?


Good morning. The case is this, I have this html view:


<div ng-controller="generalView" class="index">

    <!--  as vm -->
    <div class="container-fluid mainContainer">
        <div class="row" style=" margin-top: .5em;">

            <div class="col-xs-2 sideBar" id="mainGrl" ng-cloak>

                <h2><a href="#" onclick="collapseMainGrl();" style="text-decoration: none; color:#fff;">@Resources.Translate.general</a></h2>
                <div ng-include=" '/Home/mainGeneral'"> </div>

            </div> <!-- Main General // 2 columnas -->

            <img class="imgTenarisLogo" src="/Images/Tenaris_Logo.png" style="width:1000px; margin-top:6em;" ng-show="showLogo" ng-cloak />

            <div class="col-xs-10" ng-show="statusShow" id="zoneFilters" ng-cloak>

                <!--  VISTA MUESTRA -->
                <div class="row" id="vistaMuestra" ng-if="showES">
                    <div class="col-xs-12 " id="panel-body" ng-show="statusShow">
                            <a href="#" style="position: absolute; text-decoration: none; color:#fff ; right: 97%;" onclick="collapseMainGrl();">
                                <i class='glyphicon glyphicon-list-alt'>

                            <a href="" data-target="#filtersCollapse" style="text-decoration: none; color:#fff; margin-left:-20px; position:absolute" data-toggle="collapse" onclick="collapseFilter()">
                            <a href="#" style="text-decoration: none; color:#fff ; float:right;" ng-click="showMills()" id="">
                                <i class='glyphicon glyphicon-retweet' style="padding:0.3em">
                            </a><i style="float: right; color: white;">@Session["mill"] </i>

                   @*     <div class="collapse in" id="filtersCollapse">*@
                            <!-- FILTROS MUESTRA -->
                            <div ng-controller="filterControllerES">
                                <form ng-if="showES" name="filtrosMuestra">
                                    <table class="table table-bordered table-condensed">

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.expedient</th>
                                            <td class="col-xs-2"><input type="text" name="expedientSearchES" ng-model="filterES.Expedient" class="col-xs-2 inputInlineEdit" />{{input_Expedient}}</td>

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> @Resources.Translate.cycle</th>
                                            <td class="col-xs-2"><input type="text" name="cycleSearchES" ng-model="filterES.Cycle" class="col-xs-2 inputInlineEdit" />{{input_Cycle}}</td>

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> @Resources.Translate.heat</th>
                                            <td class="col-xs-2"><input type="text" name="heatSearchES" ng-model="filterES.Heat" class="col-xs-2 inputInlineEdit" />{{Heat}}</td>

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> @Resources.Translate.Lot</th>
                                            <td class="col-xs-2"><input type="text" name="lotSearchES" ng-model="filterES.Lot" class="col-xs-2 inputInlineEdit" />{{lot}}</td>
                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.OIS</th>
                                            <td class="col-xs-2"><input type="text" name="OISSearchES" ng-model="filterES.OIS" class="col-xs-2 inputInlineEdit" /></td>

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.HTR</th>
                                            <td class="col-xs-2"><input type="text" name="HTRSearchES" ng-model="filterES.HTR" class="col-xs-2 inputInlineEdit" /></td>

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.origin</th>
                                            <td class="col-xs-2">
                                                <select class="col-xs-2 inputInlineEdit" name="originSearchES" ng-model="filterES.Origin">
                                                    <option value="value_0">....</option>
                                                    <option value="value_1"> origen_1 </option>
                                                    <option value="value_2"> origen_2 </option>

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.modifier</th> <!-- attr sampler -->
                                            <td class="col-xs-2">
                                                <multiselect name="SelectionModifier[]" multiple="true" id="mult" ng-model="filterES.SelectionModifier" options="mod.desc for mod in ListModifiers">

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.dateFrom</th>
                                            <td class="col-xs-2">
                                                <input type="text" ui-date="dateOptions" ui-date-format="dd/mm/yy" name="DateFromSearch" ng-model="filterES.DateFrom" style="cursor:pointer" class="col-xs-2 inputInlineEdit" value="{{aDate}}" />
                                                @*<valida-fechas fecha="filterES.DateTo" fecha2="filterES.DateFrom" ng-model="filterES"></valida-fechas>
                        <span ng-show="filtrosMuestra.DateFromSearch.$invalid">NIF no válido.</span>*@


                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.dateTo </th>
                                            <td class="col-xs-2">
                                                <input type="text" data-ui-date="dateOptions" name="DateToSearchES" ui-date-format="dd/mm/yy" ng-model="filterES.DateTo" style="cursor:pointer" class="col-xs-2 inputInlineEdit" value="{{aDate}}" />


                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.idSampler</th>
                                            <td class="col-xs-2"><input type="text" name="idSamplerSearchES" ng-model="filterES.IdSampler" class="col-xs-2 inputInlineEdit" /></td>

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.typeSampler</th>
                                            <td class="col-xs-2">

                                                <multiselect name="SelectionModifier[]" multiple="true" id="mult" ng-model="filterES.Selection" options="mod.desc for mod in ListTipoMuestra">


                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader">@Resources.Translate.hamper </th>
                                            <td class="col-xs-2">
                                                <select class="col-xs-2 inputInlineEdit" name="hamperSearchES" ng-model="filterES.Hamper" disabled>
                                                    <option value="value_0">....</option>
                                                    <option value="value_1"> testing </option>
                                                    <option value="value_2"> Aca multiSelect Angular </option>

                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> </th>
                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> </th>
                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> </th>
                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> </th>
                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> </th>
                                            <th class="col-xs-1 backgroundGrey fontSize11 colorColumnHeader"> </th>


                            <!-- BOTONES BUSCAR LIMPIAR EXPORTAR MUESTRA -->
                            <div class="btn-general">
                                <button id="btnSearchGrl" class="btn btn-default search" ng-click="btnSearchGrl(this)">          @Resources.Translate.search </button>
                                <button id="btnReset" class="btn btn-default reset" ng-click="btnReset(this)" type="reset"> @Resources.Translate.reset  </button>
                                <button id="btnExport" class="btn btn-default excelExport" ng-click="excelExport(this)">           @Resources.Translate.export </button>
                       <!--  </div> -->
                    <!-- TABLA DATOS MUESTRA -->
                    <ng-controller ng-controller="tableControllerES">
                        <div class="col-xs-12" id="sectionTable">

                            <div ng-if="showES" ng-init="gridOnload()">
                                <h4 id="table1" style="margin-top:.09em;">

                                    <label class="buttonShowAll" ng-class="{disabled: btnShowState}" ng-click="showAllColumns(btnShowState)">
                                        Mostrar Columnas
                                        <i class='glyphicon glyphicon-check' style="padding:0.3em">  </i>
                                    <label style="margin-left:45px;position:absolute;">  @Resources.Translate.sampler </label>

                                <div ui-grid="samplerGridES" ui-grid-pagination ui-grid-selection ui-grid-cellnav ui-grid-auto-resize ui-grid-column-resizer class="grid" style="height: 217px;">  </div>

                        <div ng-show="statusShow" ng-cloak>
                            <div class="col-xs-12 tableSampler" id="zoneTabs">

                                <div id="tabSamplerDetails">
                                    <h4> @Resources.Translate.details</h4>

                                    <ul id="NavsTabs" class="nav nav-tabs">

                                        <li> <a href=" #" ng-if="tabGeneralEvents" ng-class="btnEventos" ng-click="setTabGeneralEvents()">@Resources.Translate.events</a> </li>
                                        <li> <a href="#" ng-if="tabProduct" ng-class="btnProd" ng-click="setTabProduct()">         @Resources.Translate.product    </a> </li>
                                        <li> <a href="#" ng-if="tabSampler" ng-class="btnMuestra" ng-click="setTabSampler()">         @Resources.Translate.sampler    </a> </li>
                                        <li> <a href="#" ng-if="tabSpecimen" ng-class="btnProbeta" ng-click="setTabSpecimen()">        @Resources.Translate.specimen   </a> </li>
                                        <li> <a href="#" ng-if="tabTest" ng-class="btnEnsayo" ng-click="setTabTest()">            @Resources.Translate.test       </a> </li>

                                <!-- PANELES DETALLES MUESTRA -->
                                <div class="tblIncludes">
                                    <!-- tab EVENTOS -->
                                        <div ng-if="isGeneralEvent == 'ES'" class="generalEvent" ng-include="'/EventSampler/GeneralEvents'"> </div>

                                    <!--  tab PRODUCTO-->
                                        <div ng-if="isProduct == 'ES'" ng-include="'/EventSampler/tabProduct'"> </div>

                                    <!-- Tab MUESTRA -->
                                        <div ng-if="isSampler == 'ES'" ng-include="'/EventSampler/tabSampler'"> </div>





            <div class="col-xs-10" ng-if="showInc" id="homeVT">
                <div ng-include="'/visualizationTests/Index'"></div>


    <!-- Modal: para devolver mensajes de error -->
    <div class="modal fade bd-example-modal-lg" tabindex="-1" id="modalResponseFail" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content kkuat">

                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    <h4 class="modal-title">Fail Response</h4>

                <div class="modal-body" id="errorMsgFail"></div>

                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Cerrar</button>

            </div><!-- /.modal-content -->
        </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->

</div>  <!-- cierre: ng-app="index" -->

As you will see I have two controllers filterControllerES and tableControllerES , these in turn inherit from the parent controller generalView that is at the beginning of the block.

I try to create a variable in the $scope of generalView from filterControllerES in this way:

$scope.$parent.filterES = new FilterEventSampler({});

Since in theory the only parent of filterControllerES is generalView . The question is do not believe me.

I started analyzing with Angularjs Batarang and found that the variable filterES creates it in another side:

Create it in


Why was the variable created there?

Then to create the variable in generalView I have to elbow:

    $scope.$parent.$parent.filterES = new FilterEventSampler({});

In this case, it works.


asked by Matias Llanos 29.09.2016 в 16:11

1 answer


Remember that many policies such as ng-if and ng-repeat also create scopes.

In your case you have

ng-controller="generalView"                => $scope
    ng-if="showES"                         => $scope.$id = 6 // Este es el que ves
        ng-controller="filterControllerES" => $scope

So that you do not have to be doing $parent.$parent.$parent... you can use the angular inheritance system and create the properties in objects instead of directly in $scope

$scope.filter = { };

$scope.filter.filterES = new FilterEventSampler({});

This way it does not matter how many levels you have, you will always access the correct property, as long as you do not hide it in the lower levels with something like

 $scope.filter = { };

 var $hijo = $scope.$new();

 $hijo.filter = 'valor';

The value of $scope.filter will not be deleted but you will not be able to access it in the children scopes. This can happen to you in the view automatically with directives like ng-model and ng-init so always try to use different properties between parent-child controllers.

It is important that you understand that if you make a directive that has isolated scope and you try to access the properties of $parent it will not work since these directives do not inherit from anyone. In spite of that you can still access the $rootScope using the property $root .

Recapitulating the directives with isolated scope are those that are created with a object in the scope or in bindToController

return {
    scope: { /* bindings*/}

// Si usas controller y bindToController

return {
    controller: '...',
    controllerAs: '...'
    bindToController: { /* bindings*/ }

Only use dot notation in your favor.

Read $ scope vs. this in angularjs

answered by 29.09.2016 / 17:07