2015-06-01 90 views
0

我遇到了一種情況,我需要根據下拉列表中選定的值更改輸入框的輸入類型。換句話說,如果用戶從下拉列表中選擇「字符串」,那麼輸入的類型應該是「文本」等。我決定創建一個指令因爲我仍然在學習Angular,所以我也不會複製塊的代碼遍佈整個地方(我需要這個不止一次)。AngularJS指令具有雙向綁定和ng-change

這是我嘗試的內容:

(function() { 
    "use strict"; 

    angular 
     .module('app') 
     .directive('dynamicTypeInput', dynamicTypeInput); 

    function dynamicTypeInput() { 
     return { 
      replace: true, 
      restrict: 'AE', 
      require: ['ngModel', '^form'], 
      scope: {type: '=', placeholder: '@'}, 
      templateUrl: 'app/common/dynamic-type-input/dynamic-type-input.tpl.html', 
      link : function(scope, element, attrs, ngModel){ 

       //Watch for changes to ngModel, update scope.inputValue 
       scope.$watch(function(){ 
        return ngModel[0].$modelValue; 
       }, function (value){ 
        scope.inputValue = value; 
       }); 

       //Watch inputValue, update the model 
       scope.$watch('inputValue', function(value){ 
        ngModel[0].$setViewValue(value); 
       }); 

       //Setup ng-change 
       if (attrs.ngChange) { 
        ngModel[0].$viewChangeListeners.push(function() { 
         scope.$eval(attrs.ngChange); 
        }); 
       } 
      } 
     }; 
    } 
})(); 

注:模板僅僅是一個ng-switch該選擇的基礎上scope.type值和輸入都結合scope.inputValue適當的輸入框。

我用this這個問題的答案來幫助我添加添加ng-change屬性並正確激發的功能。根據這個答案,我需要從孤立的範圍中刪除ngModel,我不知道爲什麼這是必需的,但如果有人能解釋它,我會很感激。

從隔離範圍中刪除ngModel使得更難以使用初始值實例化僞指令,或者在主控制器中更改模型時更新僞指令,因此我現在觀察ngModel[0].$modelValue並更新本地值(如果它發生更改)。

雖然該指令的工作原理與我所期望的一樣,但它似乎有點複雜和低效,難道我無法以更簡單的方式實現我想要的嗎?

回答

0

對引用的SO問題使用second answer我解決了需要從隔離範圍中刪除ngModel以便使ngChange正常工作的問題。這簡化了指令,我可以使用雙向綁定。

最後的指令:

(function() { 
    "use strict"; 

    angular 
     .module('app') 
     .directive('dynamicTypeInput', dynamicTypeInput); 

    dynamicTypeInput.$inject = ['$timeout']; 

    function dynamicTypeInput($timeout) { 
     return { 
      replace: true, 
      restrict: 'AE', 
      require: ['ngModel', '^form'], 
      scope: {ngModel: '=', type: '=', placeholder: '@', ngChange: "&"}, 
      templateUrl: 'app/common/dynamic-type-input/dynamic-type-input.tpl.html', 
      link: function (scope, element, attrs, ngModel) { 

       scope.$watch('ngModel', function() { 
        $timeout(scope.ngChange); 
       }); 

      } 
     }; 
    } 
})();