web-dev-qa-db-ja.com

AngularJS-カスタムディレクティブのngModelの値を変更する方法は?

私のディレクティブを見てみましょう:

angular.module('main').directive('datepicker', [
function() {
    return {
        require: '?ngModel',
        link: function(scope, element, attributes, ngModel) {
            ngModel.$modelValue = 'abc'; // this does not work
            // how do I change the value of the model?

だから、ng-modelの値をどのように変更しますか?

42
Sady

さまざまな方法があります。

  1. $setViewValue()は、ビューとモデルを更新します。ほとんどの場合、それで十分です。
  2. モデルからビューを切断したい場合(たとえば、モデルは数字であるが、ビューは数千の区切り文字を含む文字列です)、$viewValueおよび$modelValueに直接アクセスできます。
  3. ng-modelの内容も上書きする場合(たとえば、ディレクティブが小数点以下の桁数を変更し、モデルも更新する)、スコープにngModel: '='を挿入し、scope.ngModelを設定します

例えば.

  return {
     restrict: 'A',
     require: 'ngModel',
     scope: {
         ngModel: '='
     },
     link: function (scope, element, attrs, ngModelCtrl) {

        function updateView(value) {
            ngModelCtrl.$viewValue = value;
            ngModelCtrl.$render(); 
        }

        function updateModel(value) {
            ngModelCtrl.$modelValue = value;
            scope.ngModel = value; // overwrites ngModel value
        }
 ...

リンク:

49

複雑なバインディング式を使用するには、 $ parse サービスとassignメソッドを使用する必要があります。

詳細については、ng-confのこのビデオをご覧ください-ng-modelディレクティブを使用してできることのすべては次のとおりです。 https://www.youtube.com/watch?v=jVzymluqmg4

app.directive('datepicker', ['$parse',
    function($parse) {
        return {
            require: '?ngModel',
            link: function(scope, element, attributes, controller) {
                // $parse works out how to get the value.
                // This returns a function that returns the result of your ng-model expression.
                var modelGetter = $parse(attributes['ngModel']);
                console.log(modelGetter(scope));

                // This returns a function that lets us set the value of the ng-model binding expression:
                var modelSetter = modelGetter.assign;

                // This is how you can use it to set the value 'bar' on the given scope.
                modelSetter(scope, 'bar');

                console.log(modelGetter(scope));
            }
        };
    }
]);
28
Sly_cardinal

あなたが試したのは実際に動作しています: このPlunkerを参照

この方法でモデルを変更しても、controller.$render()を呼び出して新しいcontroller.$viewValue

しかし、単に$scope value(あなたがそれを知らない限り、しかしそれは奇妙だろう):

angular.module('main').directive('datepicker', [function() {
    return {
        require: '?ngModel',
        link: function(scope, element, attributes, controller) {
          var model = attributes['ngModel'];
          scope[model] = 'bar';
        }
    };
}]);

そして、あなたのhtmlで:

<input ng-model="yourVariable" datepicker>

EDIT:(動的ソリューション)

angular.module('main').directive('datepicker', [function() {
    return {
        require: '?ngModel',
        link: function(scope, element, attributes, controller) {
          // get the value of the `ng-model` attribute
          var model = attributes['ngModel'];

          // update the scope if model is defined
          if (model) {
            scope[model] = 'bar';
          }
        }
    };
}]);
4
glepretre

これは私のサイトのDatePickerに対して機能します

link: function(scope, elem, attrs, ngModel) {
         scope.$apply(function(){
             ngModel.$viewValue = value;
         }
} 
1
dball

これが私が出会った中で最高の説明です。これは私にとって大きな助けとなり、ここで他の多くの回答から詳細をまとめています。

ヒント:記事全体を読み飛ばすのではなく、記事全体を読むように注意してください。

https://www.nadeau.tv/post/using-ngmodelcontroller-with-custom-directives/

1
John Rix