2013-11-04 82 views
4

這裏是我的問題:我有一個控制,我想在AngularJS中作爲一個屬性指令(實際上我有更多,但現在只需堅持一個),就像模型指令。我在文檔中看到了一些例子,並試圖編寫我的指令。創建AngularJS指令像ngModel數組

例如:

<input type="text" my-datepicker ng-model="appointment" /> 

這工作得很好,但是當我嘗試這與數組類型的工作問題occures。 我調試過,看看是什麼導致了這個問題,並在這類問題之後搜索了文檔。

以下是我第一次嘗試:

.directive('myAnything', function(){ 
return { 
    restrict: 'A', 
    require: '?ngModel', // get a hold of NgModelController 
    link: function (scope, element, attrs, ngModel) { 
     if (!ngModel) return; // do nothing if no ng-model 

     // initialize my control on the element 
     // ... 

     // Specify how UI should be updated 
     ngModel.$render = render; 

     // Listen for change events to enable binding 
     element.on('change', function() { 
      scope.$apply(read); 
     }); 
     read(); 

     function read() { 
      // read from controll, write to model 
      // ngModel.$setViewValue([{text:'test'},{text:'test2'},{text:'test3'}]); 
     } 
     function render() { 
      if (ngModel.$modelValue) { 
       // update controller form model - render 
       // ... 
      } 
     } 
    } 
}; 
}); 

由於我是新來AngularJS我不知道如果我的理解是正確的。到目前爲止,我發現當angular檢查更改時,它不會對數組進行深入檢查,因此我的render函數不會被調用。 下面就來證明這一點小提琴:demo

我沒有找到有關如何判斷的角度來深檢查我的模型東西,所以我看在它是如何與ngModelController完成源深,我想如果我使用ngModelController這樣的基礎控制器就可以實現深入檢查。

我成功地創建了myModelController,就像ngModelController一樣,只是$ watch調用是通過傳遞第三個參數true來進行深度檢查而完成的。

$scope.$watch(function myModelWatch() { 
       var value = ngModelGet($scope); 
       if (!angular.equals(ctrl.$modelValue, value)) { 
        ctrl.$modelValue = value; 
        ctrl.$render(); 
       } 
       return ctrl.$modelValue; 
      }, 
       function (newValue, oldValue) { 
        if (!angular.equals(newValue, oldValue)) { 
         ctrl.$render(); 
        } 
       }, 
       true 
      ); 

這個工作,比第一個解決方案,甚至更好,因爲我可以用它沒有ngModel指令是這樣的(也更優雅):

<input type="text" my-anything="listofappointments" /> 

這同樣的工作,直到我申請的是指令另一個輸入之後,它們都綁定到最後一個模型屬性。

<input type="text" my-anything="secondList" /> 

我調試,這也給我在頁面上被設置爲secondList在那裏,我發現,這就是所謂的角度指令的制定者有一個參數(IDENT)點(最後一個模型屬性)。

我的問題是,我在這裏有什麼選擇?也許我在文檔中沒有注意到這可以做什麼?這看起來像一個簡單的場景......或者我需要更深入地瞭解這是如何在角度上完成的?我的方法對這個問題甚至有用嗎?

我將不勝感激任何評論或建議!如果第二種方法是可行的,我想堅持下去,因爲它顯然更加優雅和用戶友好(沒有ng模型),但如果沒有,另一個也會很好。

順便說一句,我使用的角度v1.0.8這顯然是穩定版本。 (但我不堅持這一點)

謝謝!

回答

0

我在這裏有幾條建議。首先,我認爲你通過避免ngModel正處於正確的軌道。儘管如此,如果將指令用作元素,然後使用屬性指定數組,則可以進一步深入研究。我懷疑這會發生在SO之前,我相信this answer將對你有用。其中包含一個Plunker example,它演示了簡潔地使用數組的概念。

你描述的最後一個問題在AngularJS中很常見。它會在您嘗試重新使用指令而不隔離其範圍時發生。 AngularJS directive guide在「隔離指令範圍」一節中解釋了這個概念。所述Plunker代碼段我連接到上面並與這一塊的指令定義的隔離範圍:

scope: { 
     names: '=' 
    } 

即對於該等效代碼的簡寫:

scope: { 
     names: '=names' 
    } 

這意味着:「成立的分離物範圍,其中名稱變量綁定到名稱屬性的我的指令的元素。「

這樣,指令的每個實例都有自己的範圍,並且您不會遇到在測試中看到的衝突。

+0

感謝您的提示,但我想避免使用自定義元素,因爲我的組件需要在輸入/選擇/ div/etc等位置初始化......這是一個可能的選擇,去這條路線,但如果我可以使它像一個屬性,它會更好。 我也嘗試隔離這個組件的作用域,但它不起作用。用'='速記範圍不會更新。它沒有更新其他組件,但也沒有這樣做。 – zolipapa