2013-05-27 107 views
1

我一直在努力與此相當一段時間,我無法弄清楚如何解決這個問題。嵌套元素指令無法訪問父指令範圍

我想做一個網格指令,其中包含列指令來描述網格,但列不會是元素,只會將列添加到在網格指令的範圍內聲明的數組。

我想解釋這個問題的最好辦法是查看查看代碼:

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

    .controller('myCtrl', function ($scope, $http) { 
    }) 
    .directive('mygrid', function() { 
     return { 
      restrict: "E", 
      scope: true, 
      compile: function ($scope) { 
       debugger; 
       $scope.Data = {}; 
       $scope.Data.currentPage = 1; 
       $scope.Data.rowsPerPage = 10; 
       $scope.Data.startPage = 1; 
       $scope.Data.endPage = 5; 
       $scope.Data.totalRecords = 0; 
       $scope.Data.tableData = {}; 
       $scope.Data.columns = []; 
      }, 
      replace: true, 
      templateUrl: 'mygrid.html', 
      transclude: true 
     }; 
    }) 
    .directive('column', function() { 
     return { 
      restrict: "E", 
      scope: true, 
      controller: function ($scope) { 
       debugger; 
       $scope.Data.columns.push({ 
        name: attrs.name 
       }); 

      } 
     }; 
    }); 

這裏是HTML標記:

<body ng-app="myApp"> 
<div ng-controller="myCtrl"> 
    <input type="text" ng-model="filterGrid" /> 
    <mygrid> 
     <column name="id">ID</column> 
     <column name="name">Name</column> 
     <column name="type">Type</column> 
     <column name="created">Created</column> 
     <column name="updated">Updated</column> 
    </mygrid> 
</div> 

此外,你可以測試jsfiddle中的實際代碼:http://jsfiddle.net/BarrCode/aNU5h/

我試着用compile,c控制器和鏈接,但由於某些原因,父網格的列未定義。

我該如何解決這個問題?

編輯: 當我刪除替換,templateUrl,transclude從mygrid指令,我可以從列指令的範圍。

感謝

+1

這個成功嗎? –

+1

是的,在更高版本的angularJS中,您可以使用$ scope。$ child childHead –

回答

1

在更高版本的AngularJS中,我發現$ scope。$$ childHead做我想要的。

它仍然是新的,但它也適用於隔離範圍指令。

所以在列指令,你可以這樣做:

$scope.$$childHead.Data.columns.push({ 
        name: attrs.name 
       }); 

只要確保這個命令在格的編譯後執行。你可以這樣做,但在編譯,鏈接和控制器之間切換,因爲它們每個都有不同的加載優先級。

0

我看到你想要做什麼,但使用column指令可能不是解決問題的最好辦法。

您試圖使用可自定義的列定義grid指令。每列都有2條相關信息:訪問行數據中的值的鍵和要顯示的標題。

暫時忽略所有分頁相關的東西,這裏是解決問題的另一種方法。

首先,讓我們使用屬性來定義列信息,所以我們的HTML看起來像:

<body ng-app='app' ng-controller='Main'> 
    <grid col-keys='id,name,type' 
      col-titles='ID,Name,Type' 
      rows='rows'> 
    </grid> 
</body> 

對於JS,我們顯然需要app模塊:

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

而這裏的grid指令。它使用隔離範圍,但使用雙向綁定從其父範圍獲取行數據。注意鏈接函數如何從attrs對象中提取列信息。

該模板變得非常簡單:循環遍歷列標題來定義標題,然後遍歷rows,並在每一行循環遍歷列鍵。

app.directive('grid', function() { 
    return { 
     restrict: 'E', 
     scope: { 
      rows: '='    
     }, 
     link: function(scope, element, attrs) { 
      scope.colKeys = attrs.colKeys.split(','); 
      scope.colTitles = attrs.colTitles.split(','); 
     }, 
     replace: true, 
     template: 
      '<table>' + 
      ' <thead>' + 
      ' <tr>' + 
      '  <th ng-repeat="title in colTitles">{{title}}</th>' + 
      ' </tr>' + 
      ' </thead>' + 
      ' <tbody>' + 
      ' <tr ng-repeat="row in rows">' + 
      '  <td ng-repeat="key in colKeys">{{row[key]}}</td>' + 
      ' </tr>' + 
      ' </tbody>' + 
      '</table>' 
    }; 
}); 

和一些示例數據開始。

app.controller('Main', function($scope) { 
    $scope.rows = [ 
     {id: 1, name: 'First', type: 'adjective'}, 
     {id: 2, name: 'Secondly', type: 'adverb'}, 
     {id: 3, name: 'Three', type: 'noun'} 
    ]; 
}); 

Here it is in fiddle form.

+1

獲取您的父指令。感謝您的解釋,但我真的寧願使用我的標記方式來解決此問題,因爲在您的方式中,如果我想要要更改列訂單或向列添加更多選項,我必須通過網格中的另一個屬性傳遞它,它最終看起來非常漫長和混亂。試圖簡化標記方面的所有內容,並在指令方面做所有的努力工作。 –

+0

問題在於你在編碼JS值到你的HTML中,這與使用Angular的目標背道而馳。請注意,我只是在這裏使用字符串來簡化事情。 'colKeys'和'colTitles'可以通過隔離範圍來引用,就像在父控制器中定義的「rows」一樣,避免了「冗長和雜亂」。 – satchmorun

0

正如評論音利:

在AngularJS的更高版本可以使用$scope.$$childHead

我沒有測試它讓你的父母指令。