複数の目的で Angular ポップアップ システムを構築しています。それが機能する方法は、以下に示すように、3 つの変数が ( 、および)bitPopup
に渡されるというディレクティブがあることです。type
action
data
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
。
ポップアップをトリガーする方法は次のようになります。
- ディレクティブを含むディレクティブ内のテンプレートから、とを変更し
bitPopup
ます。$scope.popup
type
action
data
- やります
$scope.$broadcast('showPopup');
bitPopup
ディレクティブが反応し、$scope.$on('showPopup', [...]});
ポップアップが表示されます。
ここで、この非常に奇妙なことが最初の試行で機能する場合に発生します (ポップアップが正しいdata
情報で開きます) data
。
さらに奇妙なのは、最初の試行で情報をログに記録しようとしたことです。わかったことは次のとおりです。
$scope.popup
呼び出しの直前にindex.htmlに$scope.$broadcast('showPopup');
正しい情報が表示されます。$scope.data
bitPopup
ディレクティブディスプレイでnull
$scope.data
atbitFalsePositivePopup
ディレクティブは正しい情報を表示します。
2回目の試行で:
$scope.popup
at index.htmlは再び正しいです。$scope.data
bitPopup
ディレクティブで、前回の試行からの情報を表示します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;
}
}
}