1

複数の目的で Angular ポップアップ システムを構築しています。それが機能する方法は、以下に示すように、3 つの変数が ( 、および)bitPopupに渡されるというディレクティブがあることです。typeactiondata

index.html

<bit-popup type="popup.type" action="popup.action" data="popup.data"></bit-popup>

popup.js

app.directive('bitPopup', function () {
  return {
    restrict: 'E',
    template: html,
    scope: {
      type: '=',
      action: '=',
      data: '='
    },
    [***]
  }
}

ポップアップ コントローラは、タイプに基づいて異なるディレクティブをロードします。

popup.html (上記の HTML テンプレート)

<div class="pop-up" ng-class="{visible: visible}" ng-switch="type">
  <bit-false-positive-popup ng-switch-when="falsePositive" type="type" action="action" data="data"></bit-false-positive-popup>
</div>

false_positives.js (bitFalsePositivePopupディレクティブを含む)

[...]
scope: {
  type: '=',
  action: '=',
  data: '='
}
[...]

bitFalsePositivePopup次に、ディレクティブの html テンプレートにからのいくつかのプロパティが表示されますdata

ポップアップをトリガーする方法は次のようになります。

  1. ディレクティブを含むディレクティブ内のテンプレートから、とを変更しbitPopupます。$scope.popuptypeactiondata
  2. やります$scope.$broadcast('showPopup');
  3. bitPopupディレクティブが反応し、$scope.$on('showPopup', [...]});ポップアップが表示されます。

ここで、この非常に奇妙なことが最初の試行で機能する場合に発生します (ポップアップが正しいdata情報で開きます) data

さらに奇妙なのは、最初の試行で情報をログに記録しようとしたことです。わかったことは次のとおりです。

  • $scope.popup呼び出しの直前にindex.html$scope.$broadcast('showPopup');正しい情報が表示されます。
  • $scope.databitPopupディレクティブディスプレイでnull
  • $scope.dataatbitFalsePositivePopupディレクティブは正しい情報を表示します。

2回目の試行で:

  • $scope.popupat index.htmlは再び正しいです。
  • $scope.databitPopupディレクティブで、前回の試行からの情報を表示します
  • bitFalsePositivePopup同じことがディレクティブにも当てはまります。

もう1つの奇妙なことは、それを使用する$scope.$apply()と正しく機能するだけで、$apply already in progressエラーが表示されることです。$scope.$apply()これはすべて Angular イベントであるため、この場合は使用しないでください。しかし、渡されたスコープが常に一歩遅れている可能性はありますか?

そもそも私は何か間違ったことをしていますか?

編集:

amahfouz の回答により、明確化のためにさらにコードを投稿することにしました。より明確に読むために、重要でない詳細をいくつか省略しました。

index.html

<div class="falsePositives" ng-controller="falsePositives">
  <i class="fa fa-minus color-red" ng-click="triggerPopup('falsePositive', 'delete', {detection: getDetection(row.detection, row.source), source: row.source, triggers: row.triggers, hash: row.hash, date: row.date})"></i>
  <i class="fa fa-pencil" ng-click="triggerPopup('falsePositive', 'edit', {detection: getDetection(row.detection, row.source), source: row.source, triggers: row.triggers, hash: row.hash, date: row.date})"></i>

  <bit-popup type="popup.type" action="popup.action" data="popup.data"></bit-popup>
</div>

index.js

var app = require('ui/modules').get('apps/falsePositives');

app.controller('falsePositives', function ($scope, $http, keyTools, bitbrainTools, stringTools) {
  function init() {
    $scope.getDetection = getDetection;

    $scope.popup = {
      type: null,
      action: null,
      data: null
    };
  }

  function getDetection(hash, source) {
    return {
      'ids': 'BitSensor/HTTP/CSRF',
      'name': 'CSRF Detection',
      'description': 'Cross domain POST, usually CSRF attack',
      'type': [
        'csrf'
      ],
      'severity': 1,
      'certainty': 1,
      'successful': false,
      'input': ['s'],
      'errors': []
    };
  }

  $scope.triggerPopup = function (type, action, data) {
    $scope.popup = {
      type: angular.copy(type),
      action: angular.copy(action),
      data: angular.copy(data)
    };

    test();

    $scope.$broadcast('showPopup');
  };

  function test() {
    console.log('$scope.popup: ', $scope.popup);
  }
}

popup.html

<div class="pop-up-back" ng-click="hidePopup()" ng-class="{visible: visible}"></div>
<div class="pop-up" ng-class="{visible: visible}" ng-switch="type">
  <bit-false-positive-popup ng-switch-when="falsePositive" type="type" action="action" data="data"></bit-false-positive-popup>
</div>

popup.js

var app = require('ui/modules').get('apps/bitsensor/popup');

app.directive('bitPopup', function () {
  return {
    restrict: 'E',
    template: html,
    scope: {
      type: '=',
      action: '=',
      data: '='
    },
    controller: function ($scope) {
      $scope.visible = false;

      $scope.$on('showPopup', function () {
        console.log('$scope.data: ', $scope.data);
        $scope.visible = true;
      });

      $scope.$on('hidePopup', function () {
        hidePopup();
      });

      function hidePopup() {
        $scope.visible = false;
      }

      $scope.hidePopup = hidePopup;
    }
  };
});

false_positives.js

var app = require('ui/modules').get('apps/bitsensor/falsePositives');

app.directive('bitFalsePositivePopup', function () {
  return {
    restrict: 'E',
    template: html,
    scope: {
      type: '=',
      action: '=',
      data: '='
    },
    controller: function ($scope, objectTools, bitbrainTools, keyTools) {

      function init() {
        console.log('$scope.data @ fp: ', $scope.data);
      }

      function hidePopup() {
        $scope.data = null;
        $scope.$emit('hidePopup');
      }

      $scope.$on('showPopup', function () {
        init();
      });

      init();

      $scope.hidePopup = hidePopup;
    }
  }
}
4

2 に答える 2