директива angular не будет обновлять двустороннюю привязку с контроллером

У меня есть модальная директива, которая должна стать видимой при нажатии кнопки. однако значение, отвечающее за определение того, должно ли быть открыто модальное окно, которое двусторонне связано с директивой, по-видимому, не обновляется. Любые идеи?

вот директива JS:

function modalDialogSelect() {
  return {
    restrict: 'AE',
    scope: {
      show: '='
    },
    replace: true,
    transclude: true,
    link: function(scope, element, attrs) {
      scope.dialogStyle = {};
      scope.hideModal = function() {
        scope.show = false;
      };
    },
    templateUrl: "./views/directive_templates/select_modal.html"
  };
 }

директива Внутренний URL-адрес HTML:

<div class='ng-modal' ng-show='show'>
  <div class='ng-modal-overlay' ng-click='hideModal()'></div>
    <div class='ng-modal-dialog' ng-style='dialogStyle'>
      <p>Select New Customer</p>
    </div>
  </div>
</div>

кнопка, чтобы нажать и открыть модальное окно:

<button ng-click='selectCustomer = true;'>SELECT/CREATE CUSTOMER</button>

и директива modal-dialog-select в моем общем HTML

<modal-dialog-select show='selectCustomer'></modal-dialog-select>

есть идеи, почему scope.show не обновляется в моей директиве? Спасибо!


person austin809    schedule 30.06.2015    source источник
comment
Можете ли вы попробовать изменить блок link: function(scope, element, attrs) {...} в конфигурации вашей директивы на блок controller: function($scope) {...}? Тот же код внутри, но с заменой scope на $scope.   -  person ggalmazor    schedule 30.06.2015
comment
@ggalmazor Не имеет значения. Вы можете называть переменные как хотите, проблема здесь в другом.   -  person Daedalus    schedule 30.06.2015
comment
не удалось перейти от ссылки к контроллеру .... попробовать другие вещи, которые вы предложили!   -  person austin809    schedule 30.06.2015
comment
@austin809 Я удалил этот комментарий, потому что что-то не так понял.   -  person Daedalus    schedule 30.06.2015
comment
@ggalmazor Я почти уверен, что нет; пожалуйста, найдите мне документацию, подтверждающую вашу теорию; имя переменной имеет значение только при создании директивы/сервиса/контроллера/приложения, где angular в основном определяет, какой импорт нам нужен, через имена. Здесь мы ничего не импортируем. Что касается моего другого комментария, как я уже сказал, есть причина, по которой я его удалил.   -  person Daedalus    schedule 30.06.2015
comment
@Daedalus, пожалуйста, простите меня, если я вас не понимаю ... Angular передает параметры функций ссылок по положению: scope, element, attributes, controller. В контроллерах, определенных, как в примере OP (без использования формы массива, аннотаций или свойства $inject), параметры передаются в соответствии с их именами с известными объектами в контейнере внедрения зависимостей Angular. В любом случае, я хотел использовать контроллер, а не функцию ссылки, чтобы избежать возможных проблем с преждевременной привязкой области видимости, которые могут возникнуть при странных обстоятельствах (особенно с модальными окнами) в моем опыте.   -  person ggalmazor    schedule 30.06.2015
comment
@austin809, не могли бы вы попробовать сохранить логическое значение selectCustomer в свойстве объекта в родительской области? Чтобы html читался так: <modal-dialog-select show='someObj.selectCustomer'></modal-dialog-select>   -  person ggalmazor    schedule 30.06.2015
comment
@austin809 Какую версию angularjs вы используете?   -  person Daedalus    schedule 30.06.2015
comment
@ggalmazor не повезло.   -  person austin809    schedule 30.06.2015
comment
@austin809 Austin809 Раньше вы переходили на 1.3.x с устаревшей версии?   -  person Daedalus    schedule 30.06.2015
comment
Я предполагаю, что у вас действительно есть переменная области видимости в вашем контроллере, например: $scope.selectCustomer = false? Потому что он отлично работает для меня.   -  person jme11    schedule 30.06.2015
comment
@Дедал, нет. всегда использовал 1.3.x   -  person austin809    schedule 30.06.2015
comment
Проблема в модальном шаблоне. Вам нужно удалить один из последних </div>. Я подготовил codepen с вашим примером, и после этого изменения все работает.   -  person ggalmazor    schedule 30.06.2015


Ответы (3)


У вас была проблема в шаблоне вашего модального окна, который производил

Error: Template must have exactly one root element. was: 
<div class='ng-modal' ng-show='show'>
  <div class='ng-modal-overlay' ng-click='hideModal()'></div>
  <div class='ng-modal-dialog' ng-style='dialogStyle'>
    <p>Select New Customer</p>
  </div>
        </div>
</div>

После удаления последнего </div> все работает.

var app = angular.module("myApp", []);

app.controller('ParentController', function($scope) {
  $scope.selectCustomer = false;
});

app.directive('modalDialogSelect', function() {
  return {
    restrict: 'AE',
    scope: {
      show: '='
    },
    replace: true,
    transclude: true,
    link: function(scope, element, attrs) {
      scope.dialogStyle = {};
      scope.hideModal = function() {
        scope.show = false;
      };
    },
    templateUrl: "modal.html"
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js"></script>
<div ng-app="myApp" ng-controller="ParentController"> 

  <p>Flag is: {{selectCustomer}}</p>
  <button ng-click='selectCustomer = !selectCustomer'>SELECT/CREATE CUSTOMER</button>

  <modal-dialog-select show='selectCustomer'></modal-dialog-select>


  <script type="text/ng-template" id="modal.html">
    <div class='ng-modal' ng-show='show'>
      <div class='ng-modal-overlay' ng-click='hideModal()'></div>
      <div class='ng-modal-dialog' ng-style='dialogStyle'>
        <p>Select New Customer</p>
      </div>
    </div>
  </script>
</div>

person ggalmazor    schedule 30.06.2015

Это может быть забавная проблема с передачей javascript по значению, поскольку var является логическим. Честно говоря, я плохо объясняю основную причину этого.

Попробуйте передать его как объект

ng-click='selectCustomer.value = true'

Тогда ваше свойство show scope будет scope.show.value.

person Rick Willis    schedule 30.06.2015
comment
я предполагаю, что вы все еще передавали переменную как ‹modal-dialog-select show='selectCustomer'›‹/modal-dialog-select› - person Rick Willis; 30.06.2015
comment
@RickWillis Я догадывался, что это тоже может быть проблемой ... не могли бы вы написать полный пример кода с html для кнопки и модальное использование с использованием для OP, пожалуйста? - person ggalmazor; 30.06.2015

Вроде нормально работает...

function modalDialogSelect() {
  return {
    restrict: 'AE',
    scope: {
      show: '='
    },
    replace: true,
    transclude: true,
    link: function(scope, element, attrs) {
      scope.dialogStyle = {};
      scope.hideModal = function() {
        scope.show = false;
      };
    },
    template: "<div class='ng-modal' ng-show='show'><button ng-click='hideModal()'>Here's the Modal</button></div>"
  };
}

angular.module('test', [])
  .controller('testCtrl', function() {})
  .directive('modalDialogSelect', modalDialogSelect);
<script src="https://code.angularjs.org/1.3.0/angular.js"></script>

<div ng-app="test">
  <div ng-controller="testCtrl as vm">

    <button ng-click='vm.selectCustomer = true;'>SELECT/CREATE CUSTOMER</button>

    <modal-dialog-select show='vm.selectCustomer'></modal-dialog-select>

  </div>
</div>

person jme11    schedule 30.06.2015