Контроллер и привязка асинхронных переменных - PullRequest
0 голосов
/ 14 февраля 2019

Я хочу управлять отображением элементов, используя переменную, которая определена в контроллере.
Но если переменные изменяются асинхронно, мой код не работает должным образом.В моем примере я вывожу на консоль значение vm.fruit внутри методов setFruit и hasFruit.
И после установленного значения для vm.fruit в setFruit, в hasFruit vm.fruit значение равно undefined.
Есть идеи о том, как это исправить?
И я не хочу вызывать метод контроллеров внутри директивы.

UPD.Я удалил определение exampleController из asyncChoice, как предложил @LeroyStav.Я думаю, он прав.Но это не решило проблему.

angular.module('app', [])
  .controller('exampleController', exampleController)
  .directive('wrapper', wrapper)
  .directive('asyncChoice', asyncChoice);

function exampleController() {
  var vm = this;
  vm.selectMode = false;
  vm.fruit = undefined;
  vm.hasFruit = hasFruit;
  vm.selectFruit = selectFruit;
  vm.setFruit = setFruit;

  function hasFruit() {
    console.log('hasFruit: ' + vm.fruit);
    return (typeof vm.fruit !== 'undefined');
  }

  function selectFruit() {
    vm.selectMode = true;
  }

  function setFruit(fruit) {
    setTimeout(
      function() {
        vm.fruit = fruit;
        vm.selectMode = false;
        console.log(vm.fruit);
      },
      1000
    );
  }
}

function wrapper() {
  return {
    restrict: 'E',
    trancslude: true,
    controller: 'exampleController',
    controllerAs: 'vm'
  };
}

function asyncChoice() {
  return {
    template: `
  <button ng-click="selectFruit({fruit: '?'})">?</button>
    <button ng-click="selectFruit({fruit: '?'})">?</button>
  `,
    scope: {
      selectFruit: '&'
    },
    controller: 'exampleController',
    controllerAs: 'vm'
  }
}

angular.bootstrap(
  document.getElementById('root'), ['app']
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div id="root">
  <wrapper>
    <button ng-if="!vm.hasFruit()" ng-click="vm.selectFruit()">Choice fruit</button>
    <p ng-if="vm.hasFruit()">You choice <span ng-bind="vm.fruit"></span></p>
    <async-choice ng-if="vm.selectMode" select-fruit="vm.setFruit(fruit)"></async-choice>
  </wrapper>
</div>

1 Ответ

0 голосов
/ 24 февраля 2019

Я предоставляю $scope exampleController и вызываю $scope.$digest() после выполнения асинхронной операции.

angular.module('app', [])
  .controller('exampleController', exampleController)
  .directive('wrapper', wrapper)
  .directive('asyncChoice', asyncChoice);

exampleController.$inject = ['$scope'];

function exampleController($scope) {
  var vm = this;
  vm.selectMode = false;
  vm.fruit = undefined;
  vm.hasFruit = hasFruit;
  vm.selectFruit = selectFruit;
  vm.setFruit = setFruit;

  function hasFruit() {
    console.log('hasFruit: ' + vm.fruit);
    return (typeof vm.fruit !== 'undefined');
  }

  function selectFruit() {
    vm.selectMode = true;
  }

  function setFruit(fruit) {
    setTimeout(
      function() {
        vm.fruit = fruit;
        vm.selectMode = false;
        console.log(vm.fruit);
        $scope.$digest();
      },
      1000
    );
  }
}

function wrapper() {
  return {
    restrict: 'E',
    trancslude: true,
    controller: 'exampleController',
    controllerAs: 'vm'
  };
}

function asyncChoice() {
  return {
    template: `
  <button ng-click="selectFruit({fruit: '?'})">?</button>
    <button ng-click="selectFruit({fruit: '?'})">?</button>
  `,
    scope: {
      selectFruit: '&'
    },
    controller: 'exampleController',
    controllerAs: 'vm'
  }
}

angular.bootstrap(
  document.getElementById('root'), ['app']
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div id="root">
  <wrapper>
    <button ng-if="!vm.hasFruit()" ng-click="vm.selectFruit()">Choice fruit</button>
    <p ng-if="vm.hasFruit()">You choice <span ng-bind="vm.fruit"></span></p>
    <async-choice ng-if="vm.selectMode" select-fruit="vm.setFruit(fruit)"></async-choice>
  </wrapper>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...