我正在构建一个用于多种目的的 Angular 弹出系统。它的工作方式是我有一个名为 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: '='
},
[***]
}
}
弹出 Controller 然后根据类型加载不同的指令:
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', [...]});
而使用react并使弹出窗口可见。
现在,这个非常奇怪的事情发生在第一次尝试时起作用的地方(弹出窗口打开时显示正确的 data
信息),但第一次尝试后它将显示 data
从之前的尝试来看。
现在更奇怪的是,我尝试在第一次尝试时记录信息,结果发现:
-
$scope.popup
在调用$scope.$broadcast('showPopup');
之前的 index.html显示正确的信息。 -
$scope.data
在bitPopup
指令显示null
-
$scope.data
在bitFalsePositivePopup
指令显示正确的信息。
第二次尝试时:
-
$scope.popup
index.html 再次正确。 -
$scope.data
在bitPopup
指令显示前一次尝试的信息 - 同样适用于
bitFalsePositivePopup
指令。
另一个奇怪的事情是当我使用 $scope.$apply()
时它确实工作正常,只是显示 $apply already in progress
错误。我知道我不应该使用 $scope.$apply()
在本例中,因为都是 Angular 事件。但怎么可能传递的范围总是落后一步呢?
我一开始就做错了什么吗?
编辑:
因为amahfouz's answer我决定发布更多代码以进行澄清。为了更清晰地阅读,我省略了一些不重要的细节。
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;
}
}
}
最佳答案
如果没有其余的代码,我只能猜测:您要么需要在显示弹出窗口时使用 promise ,要么使用 $apply 服务来更改弹出窗口的可见性。
关于javascript - $scope 传递有延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34535847/