2015-10-20 57 views
2

我正在編寫一個過濾器,它將格式化我的聯繫人窗體中的電話號碼但是由於某種原因,輸入中的值永遠不會更新,我不知道我在做什麼錯誤。角度過濾器不能正常工作

這裏是我的HTML:

<div class='form-group'> 
    <input name='phone' ng-model='home.contact.phone' placeholder='(Area code) Phone' required ng-bind='home.contact.phone | phone' /> 
</div> 

,這裏是我的過濾器:

(function() { 
    'use strict' 

    angular 
     .module('Allay.phoneFilter', []) 
     .filter('phone', function() { 
      return function (phone) { 
       if(!phone) return ''; 

       var res = phone + '::' // Since this isn't working, I'm doing something super simple, adding a double colon to the end of the phone number. 
       return res; 
      } 
     }); 
})(); 

我不知道,如果你需要這一點,但這裏的控制器:

(function() { 
    'use strict' 

    angular 
     .module('Allay', [ 
      'Allay.phoneFilter' 
     ]) 
     .controller('HomeController', function() { 
      var home = this; 
     }); 
})(); 

如果我在過濾器的'return res'之前添加了一個alert(res),我看到了我期望'123 ::'的值,但是它的輸入值是self還只是123

+0

我該怎麼做?我在文檔中沒有看到需要$ scope的任何內容。$ apply()和一個過濾器。 – efarley

+0

好吧,由於您剛剛更改了問題的內容以使我的答案無效,因此我會假設其他答案中的一個會有所幫助。 – Claies

回答

1

您需要創建指令來改變你的ngModel,像這樣:

<input name='phone' ng-model='contact.phone' placeholder='(Area code) Phone' required phone-format /> 

JS小提琴:在HTML

.directive('phoneFormat', function() { 
    return { 
     require: 'ngModel', 
     link: function(scope, elem, attrs, ctrl) { 

      var setvalue = function() { 
       elem.val(ctrl.$modelValue + "::"); 
      }; 

      ctrl.$parsers.push(function(v) { 
       return v.replace(/::/, ''); 
      }) 


      ctrl.$render = function() { 
       setvalue(); 
      } 

      elem.bind('change', function() { 
       setvalue(); 
      }) 

     } 
    }; 
}); 

使用http://jsfiddle.net/57czd36L/1/

+1

沒有必要創建一個指令,他使用過濾器的方法是正確的。 – Cyberdelphos

+2

@Cyber​​delphos這裏是你的解決方案http://jsfiddle.net/wuxfurdn/和在控制檯中是錯誤 - 不可分配的模型表達式:contact.phone |電話() –

+0

我認爲這個想法是使用指令來修改DOM行爲或向控制器添加行爲並在轉換值時使用過濾器,例如我正在做的。 – efarley

-2

您應該刪除你的「ng-bind」是因爲你正在過濾它,所呈現的是ng模型中的內容。使用值來代替。

<input name='phone' ng-model='home.contact.phone | phone' value="{{contact.phone | phone}}" /> 

看到工作示例:JsFiddle

+0

他已經改變/糾正了雙模塊定義在他的問題中...所以只有你的第一點適用於這裏... – Cyberdelphos

+0

由於某些原因,你的例子中的輸入不能改變。它固定在任何初始值。 – efarley

+0

@efarley - 更新我的小提琴 –

1

雖然過濾器模塊是一個好方法,我個人使用一個「A」型指令做骯髒的工作。更改元素值將影響它的ng模型。

但是,我只會建議這種解決方案,如果您的實際數據處理可以在3-4行代碼中求和;否則需要更徹底的方法。

這是將刪除任何東西是不是整數的例子:

(function() { 
'use strict' 
angular.module('Allay') 
    .directive('phoneValidator', function() { 
     return { 
      restrict: 'A', 
      link: function(scope, element, attrs) { 
       angular.element(element).on('keyup', function() { 
         element.val(element.val().replace(/[^0-9\.]/, '')); 
       }); 
      }); 
     } 
    }); 
})(); 

,比你的HTML模板:

<input name="phone" ng-model="home.contact.phone" placeholder="(Area code) Phone" phoneValidator required/>` 
1

您輸入的ngBind說法並不正確。從文檔,

ngBind屬性告訴角來代替與給定表達式的值指定的HTML元素的文本內容,並且當該表達式的值改變

更新文本內容

您不需要替換<input>元素的文本內容,這是沒有意義的。你可以去繼承使用指令的NgModelController的格式化管道像

app.directive('phoneFormat', function() { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function (scope, element, attrs, ngModel) { 
      ngModel.$formatters.push(function (value) { 
       if (value) 
        return value + '::'; 
      }); 
     } 
    } 
}); 

然後,在你的HTML,

<input ng-model='home.contact.phone' phone-format /> 

如果你想保持你寫的過濾器(用於其他用途),在該指令實際上你可以重新使用它像

app.directive('phoneFormat', [ '$filter', function ($filter) { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function (scope, element, attrs, ngModel) { 
      ngModel.$formatters.push($filter('phone')); 
     } 
    } 
}]); 

$filter('phone')只是返回'phone'下注冊的過濾功能。這是一個Plunker


注意,該解決方案將只格式的數據當您更改NgModelController$modelValue,例如像

$scope.$apply('home.contact.phone = "123-456-7890"'); 

如果你正在尋找的東西更新/格式化輸入的價值當用戶輸入時,這是一個更復雜的任務。我推薦使用類似angular-ui/ui-mask的東西。

+1

@xRoyDot,同意你的意見,這是一個正確的方向。但是,在用戶打字時「屏蔽」輸入值是一件非常困難的工作。如果操作不當,對用戶來說非常煩人。例如,在編輯輸入的中間時,您必須擔心保留光標位置。 ui-mask _does_很好地完成任務。 –