2013-08-29 62 views
4

我有一個角度的應用程序設置如下。 Ng-repeat包含li元素,每個元素有2個輸入(好於2個,但是對於這個演示我有2個)。

指令設置控制器。

HTML

<li ng-repeat="lw in lw_list" my-lw ng-model="lw" >    
    <input my-cell ng-init="init(lane , $index , 'name')" ng-class="'lib_name inline_div'" type='text'  value="{{ lw.library.name }}" > 
    <input my-cell ng-init="init(lane , $index , 'volume') "ng-class="'number_field'"  type="number" ng-model='volume' />  
</li>      

的javascript

angular.module('Demo').directive("myCell", function(CellStore){ 
    return { 
      controller : 'CellCtrl' , 
     }; 
}) ; 


angular.module('Demo').controller('CellCtrl' , function($scope , CellStore){ 
    $scope.init = function(lane, row, column){ 
     $scope.row = row ; 
     $scope.column = column ; 
     console.log("init" , $scope.$parent); 
     CellStore.addCell( lane.lane, row, column , $viewValue) ; 
    } ; 
}) ; 

這樣的想法是所創建的每個輸入時,它將調用init函數,其將存儲在嵌套散列的輸入值(對於稍後檢索)。但是我不知道如何從控制器中訪問$ viewValue變量(輸入包含的值)。

+0

你爲什麼不把'lw'傳入init函數? – BoxerBucks

+0

這是做到這一點的一種方式,但我的應用程序有一些輸入元素(我只在這裏放置兩個來簡化示例)。 如果我可以訪問輸入元素的模型,它會使代碼更通用和可重用。 –

+0

如何報廢控制器並在指令的鏈接功能中執行init?您將有權訪問當前的所有範圍。將您的數據作爲屬性傳遞給指令。 – BoxerBucks

回答

2

正如@BoxerBucks所說,重構你的代碼到一個link函數,並從那裏做鏈接。您也可以取消ng-init方法,因爲在創建指令時會調用鏈接函數。

首先,我稍微改變了指令,因此它需要的列名my-cell的屬性值(lw對象和$index都在範圍內,因此沒有必要通過他們):

<li ng-repeat="lw in lw_list" >    
    <input my-cell="name" ng-class="'lib_name inline_div'" type='text' ng-model="lw.name" > 
    <input my-cell="volume" ng-class="'number_field'" ng-model='lw.volume' />  
</li> 

然後鏈接功能與CellStore註冊此:

app.directive("myCell", function(CellStore){ 
    return function(scope, elem, attrs) { 
     CellStore.addCell(scope.lw, scope.$index, attrs.myCell); 
    }; 
}); 

最後,addCell方法:

app.service('CellStore', function() { 
    this.addCell = function(lw, row, column) { 
     console.log('add cell:', lw.name, row, column, lw[column]); 
    }; 
}); 

http://jsfiddle.net/9Lmwj/2/

我不完全確定你的數據結構,但我希望這是一個有益的開端。

0

你可以把初始化代碼的指令,並在傳遞數據,您需要:

<input my-cell ng-class="'lib_name inline_div'" type='text' value="{{ lw.library.name }}" > 

那麼這樣的指令改變的東西:

angular.module('Demo').directive("myCell", function(){ 
    return { 
      function(scope, element, attrs){} 
       scope.row = row; 
       scope.column = column; 
       scope.CellStore.addCell(scope.lane.lane, row, column, attrs.value); 
     }; 
}) ; 

既然不能請參閱其餘應用程序代碼,您可能需要更改某些變量名稱才能使其正常工作,但基本前提是僅使用指令的鏈接函數來運行初始化。此外,在指令中,您可以訪問聲明指令的繼承範圍。

+0

好吧,我正在嘗試類似的東西。假設我的鏈接函數是正確的,那麼我如何通過代碼的HTML部分中的額外參數來傳遞它? 你已經刪除了之前正在執行的ng-init。 –

+0

您可以直接從示波器中選取值,或者將它們作爲屬性傳遞並通過attrs參考<屬性名稱> – BoxerBucks

11

其他人已經解決了你的問題,但是我沒有看到你的主要問題的答案,如果你想這樣做,如何從控制器訪問$ viewValue。

你真正在做的是訪問連接到每個輸入的ngModelController的實例。如果您只需將name屬性放在您的表單元素和其中的每個輸入上,那麼他們的控制器將可通過$scope訪問。 (由於您使用的是ng-repeat,因此您需要某種動態命名方案,以便您可以覆蓋它們,也可以迭代它們。)

一旦你命名的一切,來獲得實例,它只是:

var instance = $scope.formName.inputName; 

而且$ viewValue應該是:

instance.$viewValue 

一旦你得到了這個引用,你也可以使用ngModelController上的其他方法,如

instance.$setValidity(); 

編輯:你可以玩這個,看看它是如何在this Codepen上附加一些驗證問題。

+2

這是一個很好的答案,應該是所選的一個...... 這說明了在說您正在使用ui.bootstrap的typeahead,並需要進行自定義orderBy或過濾函數,並且$ modelValue未同步到$ viewValue。 – jusopi

+0

這應該是答案。 – NMSL

+0

有沒有一種方法來訪問它沒有窗體? – tonestrike

相關問題