2013-12-11 64 views
1

我正在使用AngularJS大約一個星期,並且我有一個自定義指令的問題,我無法真正理解。 我的主要目標是使用$ http服務在控制器中加載json數據的指令中創建一個html表。作用域在AngularJS指令中未定義,在控制器中有ajax請求

我有我的觀點模板。如果我使用ng-repeat或表達式這樣的Angular指令,似乎數據被正確加載並綁定到範圍,並且我可以呈現我的視圖。

但是,如果我在文檔根目錄中使用自定義指令,它會在控制器發送請求之前觸發。所以當我在鏈接函數scope.myData中使用範圍是未定義的。 但是如果我在ng-repeat中使用自定義指令,我可以訪問本地作用域。我不明白爲什麼Angular指令會在數據加載之後觸發,以及爲什麼我的火災會在之前發生。我錯過了什麼?

實際上,我的數據實際上比樣本更復雜,我必須在自定義指令中分析它們以生成我的html表格:使樣本數據中的某些特定屬性(如組名)的rowspan或colspan。

任何幫助將是有用的,多謝提前。

這裏我的示例代碼。

app.js

angular.module('myApp', [ 
    'ngRoute', 
    'myApp.filters', 
    'myApp.services', 
    'myApp.directives', 
    'myApp.controllers' 
]). 
config(['$routeProvider', function($routeProvider) { 
    $routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'}); 
    $routeProvider.when('/test', {templateUrl: 'partials/test.html', controller: 'TestCtrl'}); 
    $routeProvider.otherwise({redirectTo: '/view1'}); 
}]); 

controllers.js

angular.module('myApp.controllers', []). 

    controller('TestCtrl',['$scope', '$http',function($scope, $http){ 
      $http.get('data/test.json').success(function(data) { 
        $scope.myData = data; 
      }); 

    }]) ; 

的test.html

<!-- this works perfectly --> 
<h3>{{myData.title}}</h3> 
<table class="table table-condensed table-bordered"> 
    <thead> 
     <tr> 
      <th ng-repeat="col in myData.cols">{{col.title}}</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr ng-repeat="row in myData.rows"> 
        <td>{{row.group}}</td> 
        <td ng-repeat="col in row.cols">{{col}}</td> 
     </tr> 
    </tbody> 
</table> 
<!-- does not work ! --> 
<table test-table></table> 

個directives.js

angular.module('myApp.directives', []). 
     .directive('testTable', ['$compile', function(compile){ 
       return{ 
        link: function(scope,elm,attrs,ctrl){ 
        for(var i = 0, l= scope.myData.rows.length; i<l; i++){ 
         var tr = angular.element(['<tr>', '</tr>'].join('')); 
         console.log(tr); 
         for(var j = 0; j<scope.myData.cols.length; j++){       
          var td = angular.element(['<td>', String(scope.myData.rows[i].cols[j]), '</td>'].join('')); 
          tr.append(td); 
         } 
         elm.append(tr); 

        } 
        compile(elm.contents())(scope); 
       } 
       } 
     }]); 

test.json

{ 
    "title" : "This is a simple sample data.", 
    "cols" : [{"title":"Group Name"},{"title":"Col1"},{"title":"Col2"},{"title":"Col3"}], 
    "rows" : [ 
     {"group" : "group A","cols":["Something","Something else","Other stuff"]}, 
     {"group" : "group A","cols":["Something","Something else","Other stuff"]}, 
     {"group" : "group A","cols":["Something","Something else","Other stuff"]}, 
     {"group" : "group B","cols":["Something","Something else","Other stuff"]}, 
     {"group" : "group B","cols":["Something","Something else","Other stuff"]} 
       ] 

} 

回答

2

有幾個方法可以做到這一點:

  1. 你可以嘗試resolve路線參數(發現它在docs)。這將延遲加載一個頁面,直到承諾解決。

  2. 你正在使用Angular就像jQuery--不要這樣做。 (這是angular newcommers的常見問題 - 請參閱this great answer。)對於您關於ng-repeat如何看待更改的問題:簡而言之,ng-repeat將監視範圍變量並對更改採取操作。您可以執行類似操作:

    scope。$ watch(「myData」,function(newval){ ... });

如果要設置行跨度,合併單元格,可能的ng-repeat擴展語法可以幫助:

<header ng-repeat-start="item in items"> 
    ... 
<footer ng-repeat-end> 

(檢查長例子here

+0

你說得對。我正在使用Angular,比如JQuery。 我將改變主意,嘗試更改我的數據框架,並使用angular指令在模板中完成所有主要工作。 也許刪除HTML表格,並使用網格或其他模板創建我的模板。 – user3090230

2

link功能只運行一次。它不會等待您的ajax請求獲取數據,並且在範圍更改時不會更新。

這與您的模板中的{{databinding}}形成鮮明對比,只要範圍發生更改,它們都會更新。

你可以看看$scope.$watch,讓您無論何時一個特定的範圍屬性更改執行的回調,像這樣:

scope.$watch('myData', function (newMyData) { 
    //Build the table and insert it into DOM 
}); 

使用{{databinding}}ng-repeat將是更Angularic做法雖然。

相關問題