2013-08-30 45 views
13

我正在嘗試爲應用程序構建模板並希望顯示帶有名稱的動態列表。所以我得到這個代碼來顯示列表並添加/刪除行;Ng-init如果數組尚未創建

<table ng-init="page.businessRows = []"> 
<thead> 
    <tr> 
     <th>Company</th> 
     <th>Contact</th> 
     <th>Phone</th> 
    </tr> 
</thead> 
    <tr ng-repeat="row in page.businessRows"> 
     <td> 
      <input type="text" ng-model="row.name" /> 
     </td> 
     <td> 
      <input type="text" ng-model="row.contact" /> 
     </td> 
     <td> 
      <input type="text" ng-model="row.phone" /> 
     </td> 
     <td> 
      <button ng-click="page.businessRows.splice($index,1)"> 
       Remove 
      </button> 
     </td> 
    </tr> 
</table> 
<button class="btn" ng-click="page.businessRows.push({})">addRow</button> 

的事情,當這個模板被加載page.busnessRows將最有可能加載行,所以我想改變ng-init僅創建空數組,如果businessRows將不會被初始化。我試過ng-init="page.businessRows = page.businessRows.length < 1 ? [] : page.businessRows但它沒有工作。我如何打算以流利的語言表達條件?

所有幫助表示讚賞。在此先感謝

回答

24

你可以這樣做,而不是:

<table ng-init="page.businessRows = page.businessRows || []"> 

更新

我看AngularJS的解析器代碼,請注意,1.2版(目前RC)支持三元表達式。所以,如果你使用AngularJS 1.2,這也將工作(雖然比上面的代碼更詳細):

<table ng-init="page.businessRows = page.businessRows == null ? [] : page.businessRows"> 

demo這裏。

但是,你原來的代碼可能無法如果page.businessRowsnull工作,因爲解析器將無法提領的nulllength財產。所以在那裏小心一點。

+1

這解決了他問到的問題。但我認爲它不能解決嘗試使用View作爲控制器的更大問題。 –

+0

我明白你的觀點。我也很少使用ng-init。也就是說,我不能爲每個人和他們的需求說話。畢竟,指令在那裏,如果有人認爲它有助於解決他們的問題,對他們有好處。 –

3

我不認爲ng-init會正確評估條件語句。但是您可以將條件重構爲控制器函數並從ng-init調用該函數。

<table ng-init="initializeBusinessRows(page.businessRows)"> 

只是把你的條件評估在控制器範圍的功能。

1

我認爲你試圖解決錯誤的問題。

問題是,您允許在數據加載或準備好之前發生操作。第二個問題是你在範圍函數或控制器函數應該在的ng-click中使用表達式。

所以......

  1. 禁用按鈕,如果表格沒有準備好。
  2. 使用你的控制器控制這些交互。

所以這裏是一個控制器的例子。 $超時被添加來模擬數據延遲加載到您的$ scope.page變量。

app.controller('MyCtrl', function($scope, $timeout, $window) { 
    //Timeout to simulate the asynchronous load 
    //of the page object on the $scope 
    $timeout(function(){ 
    $scope.page = { 
     businessRows: [] 
    }; 
    }, 2000); 


    //scope method to add a row. 
    $scope.addRow = function(){ 
    //for safety's sake, check to see if the businessRows array is there. 
    if($scope.page && angular.isArray($scope.page.businessRows)) { 
     $scope.page.businessRows.push({}); 
    } 
    }; 

    //scope method to remove a row 
    $scope.removeRow = function(index, row) { 
    if($window.confirm('Are you sure you want to delete this row?')) { 
     $scope.page.businessRows.splice(index, 1); 
    } 
    }; 
}); 

...和HTML視圖(注意NG-殘疾人和NG-點擊)(且缺乏NG-的init):

<div ng-controller="MyCtrl"> 
    <table> 
     <thead> 
     <tr> 
      <th>Company</th> 
      <th>Contact</th> 
      <th>Phone</th> 
     </tr> 
     </thead> 
     <tbody> 
     <tr ng-repeat="row in page.businessRows"> 
      <td> 
       <input type="text" ng-model="row.name" /> 
      </td> 
      <td> 
       <input type="text" ng-model="row.contact" /> 
      </td> 
      <td> 
       <input type="text" ng-model="row.phone" /> 
      </td> 
      <td> 
       <button ng-click="removeRow($index, row)"> 
        Remove 
       </button> 
      </td> 
     </tr> 
     </tbody> 
    </table> 
    <button class="btn" ng-disabled="!page" ng-click="addRow()">addRow</button> 
    </div> 

此外,here's the obligatory Plunker for you to see this in action

+0

...同樣,您可能希望讓您的控制器設置「removeRow(row)」方法。我會很快添加。 –