標籤:

angualrJs 自定義指令link函數NgModelController Formatters 和 parsers

指令是angularJs框架提供的一個強大的功能,angularJs本身就是一個MVVM框架;

在自定義指令中,model與view之間的交互以及變化是很頻繁的,angularJs提供了兩個管道數組,$Formatters & $Parsers,讓我們在自定義指令是用來控制view&model之間的變化;

以下是官方文檔定義:

$formatters:

Array of functions to execute, as a pipeline, whenever the bound ngModel expression changes programmatically. The $formatters are not called when the value of the control is changed by user interaction.Formatters are used to format / convert the $modelValue for display in the control.The functions are called in reverse array order, each passing the value through to the next. The last return value is used as the actual DOM value.

$parsers :

Array of functions to execute, as a pipeline, whenever the control updates the ngModelController with a new $viewValue from the DOM, usually via user input. See $setViewValue() for a detailed lifecycle explanation. Note that the $parsers are not called when the bound ngModel expression changes programmatically.The functions are called in array order, each passing its return value through to the next. The last return value is forwarded to the $validators collection.

Parsers are used to sanitize / convert the $viewValue.

首先要知道,view 與model之間總是存在聯繫的,兩者之間總是會因為某些原因發生變化,用輸入,按鍵會導致view變化,業務邏輯會導致model變化等;

formatters 和 parsers都是ngModelController中的屬性 ,都是一個可執行函數數組,作為一個管道來使用;所有函數都是以管道形式執行,什麼意思呢?就說每個函數之間都是有聯繫,他們是同步的,非非同步,每個函數都是順序執行的,這個順序取決於使用者在添加可執行函數到formatter和parsers中的順序,嗯就是這樣;

除此,所有添加的進去的函數,如果需要參數,那麼這個參數就是$viewValue(第一個執行的函數)或者上一個函數的返回值,所以說如果下一個函數需要參數,當前當前函數就必須返回值;

function format(value) { if (value) { return value.toUpperCase(); }}ngModel.$formatters.push(format);

function parse(value) { if (value) { return value.toLowerCase(); }}ngModelController.$parsers.push(parse);

這些添加進去的可執行函數都不是我們手動執行,那麼他們都會在什麼時候以怎樣的方式執行呢?

對於formatters屬性,會有實時監聽事件,當我們ng-model的數據以編程的方式改變時候,就會觸發事件,此時會以管道形式執行所有函數,包括傳參及其返回值操作;比如我們在通過js改變了值,此時就會觸發事件;

對於parsers屬性,也有事件監聽,當ng-model數據在dom端發生變化時候,就會觸發事件,執行管道函數;比較常見的就是用戶輸入/編輯值,寫了圖做為輔助理解(靈魂畫風);

在實際應用方面,這兩個屬性的很好應用,可以減少我們自己對數據行為的監聽;

其實細心就會發現兩個屬性所涉及範圍是對立的,所以,不管是model還是view的變化,都會有很大的幫助;

parsers主要針對ngModelController.$viewValue, 及其$setViewvalue();$viewValue是指令使用時所對應視圖的實際值,$modelValue對應指令控制器所綁定的值,$viewValue與$modelValue的聯繫是$viewValue要通過$setViewValue方法,$modelValue的變化不一定會引起$viewValue的變化;當$viewValue發生變化時候,出發parsers中的函數執行;

這裡有個例子:

<div ng-app="myApp" ng-controller="myCtrl"> <input ng-model="data" type="text" ng-click="ddd()" test /> <span ng-click="changeModel()">{{data}}</span></div>

angular.module(myApp, []).controller(myCtrl, function($scope){ $scope.data = yellow; $scope.changeModel = function() { $scope.data = yellow; }}).directive(test, function(){ return { require: ngModel, link: function(scope, elem, attrs, ngModel){ ngModel.$formatters.push(function(value){ //formats the value for display when ng-model is changed return brown; }); ngModel.$parsers.push(function(value){ //formats the value for ng-model when input value is changed return green; }); }, controller: function($scope,$transclude,$compile,$element) { } };});

可以點擊鏈接運行實時觀察變化;

更多請參考官方文檔

推薦閱讀:

AngularJS搭配什麼後端框架比較合適?
前端每周清單半年盤點之 Angular 篇
知乎網站 OAuth 登錄彈窗是怎麼設計的?
以worktile為例,怎麼分析AngularJs的架構方式呢?如果可以畫圖示之,感激不盡

TAG:AngularJS |