2015-07-03 114 views
40

我在我的angularJS應用程序中有兩個自定義指令。一個作爲父母,另一個作爲孩子。我正在嘗試訪問子指令內的父級範圍。但我沒有得到所需的輸出。自定義子級指令訪問父級的範圍

<div ng-controller="CountryCtrl"> 
{{myName}} 
    <div ng-controller="StateCtrl"> 
     <state nameofthestate="'Tamilnadu'"> 
      <city nameofthecity="'Chennai'"></city> 
     </state> 
    </div> 
</div> 

和我的腳本看起來像

var app = angular.module("sampleApp",[]); 
app.controller("CountryCtrl",function($scope){ 
    $scope.myName = "India"; 
}); 
app.controller("StateCtrl",function($scope){ 
}); 
app.directive("state",function(){return { 
    restrict : 'E', 
    transclude: true, 
    scope : { myName : '=nameofthestate'}, 
    template:"** {{myName}} is inside {{$parent.myName}}<br/><ng-transclude></ng-transclude>" 
}}); 
app.directive("city",function(){return { 
    restrict : 'E', 
    require:'^state', 
    scope : { myName : '=nameofthecity'}, 
    template:"**** {{myName}} is inside {{$parent.myName}} which is in {{$parent.$parent.myName }}<br/> " 
}}); 

相應的jsfiddle提供https://jsbin.com/nozuri/edit?html,js,output

的輸出,我得到是

India 
** Tamilnadu is inside India 
**** Chennai is inside India which is in Tamilnadu 

和預期輸出是

India 
** Tamilnadu is inside India 
**** Chennai is inside Tamilnadu which is in India 

任何人都可以教我在這裏做錯了嗎?

+0

對不起,但你的小提琴不適合我。 –

+1

嗨http://stackoverflow.com/questions/23437113/get-property-value-from-parent-directive-within-child-directive這可能會幫助你它看起來像你想要做的 –

+1

你可以做一個自定義transclude與'transclude:'element''。構造函數在'link:function(scope,element,attrs,Ctlr,transclude){}' – gr3g

回答

28

城市指令$ parent是一個跨狀態的州指令範圍。

狀態指令的transcluded作用域繼承了$ parent作爲控制器的state指令,因此這就是爲什麼$ parent.MyName = India。

transcluded範圍的$父是狀態指令分離範圍(範圍= {}),這就是爲什麼$母體。$ parent.MyName =塔米爾納杜(角1.3更新的部分)

enter image description here

什麼細節位發生: How to access parent scope from within a custom directive *with own scope* in AngularJS?

transclude:真 - 指令創建一個新的「transcluded」孩子 範圍,這prototypically從父範圍繼承。如果 指令也創建隔離範圍,則隔行範圍和隔行範圍是兄弟。每個作用域 的$ parent屬性引用相同的父作用域。

Angular v1.3更新:如果該指令還創建隔離範圍 ,則該transcluded範圍現在是隔離範圍的子級。跨越和隔離範圍不再是兄弟姐妹。 transcluded作用域的$ parent 屬性現在引用隔離作用域。

另外Matthew的回答對於親子指導溝通是正確的。

15

這是否適合您?改編自this answer

有沒有一種簡單的方式來訪問transcluded內容的父元素,所以我們注入父控制器到子訪問其範圍。

var app = angular.module('myApp', []); 

    app.controller("CountryCtrl",function($scope){ 
     $scope.myName = "India"; 
    }); 

    app.controller("StateCtrl",function($scope){ 
    }); 

    app.directive("state",function(){return { 
     restrict : 'E', 
     transclude: true, 
     scope : { myName : '=nameofthestate'}, 
     template:"** {{myName}} is inside {{$parent.myName}}<br/><ng-transclude></ng-transclude>", 
     controller: function ($scope) { 
     this.getName = function() { 
      return $scope.myName; 
     } 
     } 
    }}); 

    app.directive("city",function(){return { 
     restrict : 'E', 
     require:'^state', 
     scope : { myName : '=nameofthecity'}, 
     template:"**** {{myName}} is inside {{parentName}} which is in {{$parent.myName }}<br/> ", 
     link: function(scope, element, attrs, ctrl) { 
     scope.parentName = ctrl.getName(); 
     } 
    }}); 
+1

yes中可用。有用。但我接受@ kwan245的答案,因爲它解釋了我做了什麼錯誤.. :)感謝Metthew –

+0

我已經使用這種方法,但在我的情況下,變量持有名稱是一個可能會改變的數組。有沒有辦法處理這種情況,因爲在這種情況下,對於我來說視圖不會更新? 我知道我可以使用手錶,但希望儘可能避免這種情況。我有一個例子: http://stackoverflow.com/questions/42676713/sharing-data-between-child-directives/42677394 –

3

當AngularJS遇到transclude時,它會在 之前克隆HTML,然後用template或templateUrl內容替換它。然後, 遇到ng-transclude時,會編譯transcluded內容,但 將其鏈接到父範圍,而不是 指令的隔離範圍。因此,transcluded內容仍然可以訪問父控制器及其內容,而指令HTML有一個 隔離範圍(或新的範圍,視情況而定)。

AngularJS並運行

1

看看我的指令sollution,它與很多parrents的。我所做的是去除跨界並需要參數。不要爲髒兮兮的html而煩惱,只是看js,簡單點就是:D

CRM.directive('inputwv', function ($compile) { 
    var getTemplate = function(contentType) { 
     var template = ''; 

     switch(contentType) { 
       case '3': 
        template = '<input type="number" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px;width:100px">' 
        break; 
       case '0': 
        template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
        break; 
       case '1': 
        template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
        break; 
       case '2': 
        template = '<textarea class="materialize-textarea teal-text" type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
        break; 
       case '4': 
        template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
        break; 
       case '5': 
        template = '<input type="date" class="datepicker" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px"><script type="text/javascript">$(\'.datepicker\').pickadate({selectMonths: true, selectYears: 15});</script>' 
        break; 
       default: 
        template = '<textarea class="materialize-textarea teal-text" type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index)" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">' 
      } 

     return template; 
} 

    var linker = function(scope, element, attrs) { 
     element.html(getTemplate(attrs.typ)).show(); 

     $compile(element.contents())(scope); 
    } 

    return { 
     restrict: "E", 
     link: linker 
    }; 
}); 
相關問題