2016-07-26 10 views
1

事前に申し訳ありませんが、指示は私の強い訴訟ではありません!Angularディレクティブでモデルとビューの両方の値を更新するにはどうすればよいですか?

私は単純な属性のみのディレクティブを持っています。その目的は、フィールド内の文字列をblurでHH:mm形式に自動的に変換することです。これはディレクティブです:

(function() { 

    'use strict'; 

    angular 
     .module('app.format-as-time') 
     .directive('formatAsTime', timeDirective); 

    timeDirective.$inject = [ 
     'isValid' 
    ]; 

    function timeDirective (isValid) { 

     return { 
      require: 'ngModel', 
      restrict: 'A', 
      link: LinkFunction 
     }; 

     function LinkFunction (scope, elem, attrs, ngModel) { 

      elem.bind('blur', function() { 

       var currentVal = ngModel.$modelValue, 
        formattedVal = ''; 

       // Format something like 0115 to 01:15 
       if (currentVal.length === 4) { 
        formattedVal = currentVal.substr(0, 2) + ':' + currentVal.substr(2, 2); 

       // Format something like 115 to 01:15 
       } else if (currentVal.length === 3) { 
        formattedVal = '0' + currentVal.substr(0, 1) + ':' + currentVal.substr(1, 2); 

       // Format something like 15 to 00:15 
       } else if (currentVal.length === 2) { 
        formattedVal = '00:' + currentVal; 
       } 

       // If our formatted time is valid, apply it! 
       if (isValid.time(formattedVal)) { 
        scope.$applyAsync(function() { 
         ngModel.$viewValue = formattedVal; 
         ngModel.$render(); 
        }); 
       } 

      }); 
     } 

    } 

}()); 

と、関連するビュー:

<div ng-controller="TestController as test"> 
    <input type="text" 
      maxlength="5" 
      placeholder="HH:mm" 
      ng-model="test.startTime" 
      format-as-time> 
    <button ng-click="test.getStartTime()">Get Start Time</button> 
</div> 

および関連コントローラー:現時点では

(function() { 

    'use strict'; 

    angular 
     .module('app.testModule') 
     .controller('TestController', TestController); 

    function TestController() { 

     var vm = this; 

     vm.startTime = ''; 

     vm.getStartTime = function() { 
      console.log(vm.startTime); 
     } 

    } 

}()); 

、ディレクティブは期待通りのビューのために動作しますが、モデル私のコントローラでは更新されません。すなわち、入力は01:15を含みますが、モデルはconsole.log() 115.

ディレクティブで

scope: { 
    ngModel: '=' 
} 

が、これは何もしませんでした:

私が使って試してみました。

私はこれを正しい方法で行いましたか?モデルとビューの両方を同期させるために追加する必要があるのは何ですか?

私がこれを間違った方法で行った場合、正しく行うにはどうすればよいでしょうか?

+0

isValidサービスはどのように見えますか? –

+0

'isValid'は、値が有効かどうかをチェックするためにいくつかの関数を公開する単なるファクトリです。 'isValid.time()'はHH:mm文字列の単なる正規表現です。面白いのは、問題がどこにあるのかです。 'isValid.time()'は、上のディレクティブでビューがレンダリングされた時点でtrueを返します。しかし、コントローラモデル 'isValid.time()'をテストしようとするとfalseが返され、モデルには事前フォーマットされた値が含まれていることが示されます。 –

+0

'ngModel。$ viewValue = formattedVal;'の代わりに 'ngModel。$ setViewValue(formattedVal);'を試してください。これは、ngModelを設定する通常のモデルパイプラインを通して値を実行する必要があります。 –

答えて

1

問題はこの行にありますngModel.$viewValue = formattedVal; Angularには、$ parserと$ validatorsを使って実行することを含むmodelValueを設定するためのパイプラインがあります。値を設定する適切な方法は、このパイプラインを通じて値を実行する$setViewValue(formattedVal)を呼び出すことです。

+0

ありがとう!私はすでにこれを試していたが動作しなかったが、私の構文は間違っていた: 'ngModel。$ setViewValue = formattedVal;' –

関連する問題