Используйте ng-модель, чтобы избежать задержки $ digest в директивах по компонентам - PullRequest
0 голосов
/ 25 мая 2018

Как вызывать любую функцию контроллера в директиве в angularJs

Я пытаюсь вызвать функцию родительского контроллера, которая не имеет ничего общего с директивой, когда значение привязки директивы изменилось.

Я просматривал вопросы и ответы в стеке, но все они связаны с передачей значения из директивы в контроллер, что не в моем случае.

Я думал, что мой случай в целом распространен, сценарийтаково: отображать сложные объекты в цикле, одно из свойств привязки объекта к директиве.и когда свойство изменилось, сделайте что-нибудь с обновленным сложным объектом.

Однако в моем коде он печатает старое значение объекта вместо обновленного.Я предполагаю, что моя функция обновления вызывается до завершения процесса $ digest.

есть предложения?

пример плунжера: https://plnkr.co/edit/bWGxEmJjNmiKCkRZTqOp?p=preview

здесь контроллер код:

  var $ctrl = this;
  $ctrl.items = [
      {id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 30}
  ];

  $ctrl.update = function(item){
    //trying to update item after changing
    console.log("updated item is: " + angular.toJson(item));
  };

вот код директивы код:

var controller = function($scope){
   var $ctrl = this;
   $ctrl.clicked = function(){
      $ctrl.value = $ctrl.value + 1;

      //calling the bind on-change function defined in controller
      $ctrl.onChange();
   }
};

return {
   restrict: 'E',
   scope: {
          value: '=',
          onChange: '&'
   },
   controller: controller,
   controllerAs: '$ctrl',
   bindToController: true,
   templateUrl: 'directive.html'
};

и HTML выглядит так:

<div ng-repeat="item in mc.items">
  <my-directive value="item.value" on-change="mc.update(item)"></my-directive>
</div>

и шаблон директивы:

<button type="button" ng-click="$ctrl.clicked()">{{$ctrl.value}}</button>

1 Ответ

0 голосов
/ 25 мая 2018

Вы правы, что функция обновления вызывается до завершения процесса $digest.

Один из подходов заключается в обновлении значения с помощью ng-model и ng-change:

<my-directive ng-model="item.value" ng-change="mc.update(item)">
</my-directive>

JS:

$ctrl.value++;
$ctrl.ngModelCtrl.$setViewValue($ctrl.value);

При таком подходе ngModelController обновит значение перед вызовом ng-change .

.Демо

angular.module('myApp', [])
.controller('myController', function(){
  var $ctrl = this;
  $ctrl.items = [
      {id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 30}
  ];

  $ctrl.update = function(item){
    //trying to update item after changing, but here it prints out old item instead of updated item.
    console.log("updated item is: " + angular.toJson(item));
  };
  
})
.directive('myDirective', function(){
    var controller = function(){
      var $ctrl = this;
      $ctrl.clicked = function(){
        $ctrl.value++;
        $ctrl.ngModelCtrl.$setViewValue($ctrl.value);
        console.log("calling clicked in directive and value is ", $ctrl.value);
      }
    };

    return {
        restrict: 'E',
        require: {ngModelCtrl: 'ngModel'},
        scope: {
          value: '<ngModel',
        },
        controller: controller,
        controllerAs: '$ctrl',
        bindToController: true,
        template: `<button type="button" ng-click="$ctrl.clicked()">
                   {{$ctrl.value}}
                   </button>`
    };
});
<script src="//unpkg.com/angular@1.6/angular.js"></script>
<body ng-app='myApp' ng-controller="myController as mc">
      <div ng-repeat="item in mc.items">
        id={{item.id}}
        <my-directive ng-model="item.value" ng-change="mc.update(item)">
        </my-directive>
      </div>
</body>

Я не совсем понимаю эти две строки:

  1. require: {ngModelCtrl: 'ngModel'}.ngModelCtrl работает как переименование ngModel, чтобы его можно было использовать в контроллере директивы?
  2. value: '<ngModel'.что делает '<'?

require: {ngModelCtrl: 'ngModel'} привязывает API контроллера ng-model к директивному контроллеру с именем ngModelCtrl.

scope: {value: '<ngModel'} создаетодносторонняя привязка атрибута ng-model к контроллеру с именем value.

Для получения дополнительной информации см.


Использование ng-model обеспечивает интеграцию с проверкойAPI ngFormController .Можно создавать пользовательские компоненты форм с несколькими входами.

Для получения дополнительной информации см.

...