[英]$scope passing has a Delay
I'm building an Angular pop-up system for multiple purposes. 我正在构建一个用于多种用途的Angular弹出系统。 The way it works is that I have a directive called bitPopup
which three variables get passed on to ( type
, action
and data
) as shown below: 它的工作方式是我有一个名为bitPopup
的指令,该指令将三个变量传递给( type
, action
和data
),如下所示:
index.html 的index.html
<bit-popup type="popup.type" action="popup.action" data="popup.data"></bit-popup>
popup.js popup.js
app.directive('bitPopup', function () {
return {
restrict: 'E',
template: html,
scope: {
type: '=',
action: '=',
data: '='
},
[***]
}
}
The popup controller then loads a different directive based on the type: 然后,弹出控制器根据类型加载另一个指令:
popup.html (The HTML template shown above) 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 (Containing the bitFalsePositivePopup
directive) false_positives.js (包含bitFalsePositivePopup
指令)
[...]
scope: {
type: '=',
action: '=',
data: '='
}
[...]
And then the html template for the bitFalsePositivePopup
directive displays some properties from data
. 然后,用于bitFalsePositivePopup
指令的html模板显示data
一些属性。
Now the way I'm triggering a pop-up works like this: 现在,我触发弹出窗口的方式如下:
bitPopup
directive i'll change $scope.popup
's type
, action
and data
. 从包含bitPopup
指令的指令内部的模板中,我将更改$scope.popup
的type
, action
和data
。 $scope.$broadcast('showPopup');
我将做$scope.$broadcast('showPopup');
bitPopup
directive will react because of $scope.$on('showPopup', [...]});
由于$scope.$on('showPopup', [...]});
bitPopup
指令将作出反应$scope.$on('showPopup', [...]});
and makes the pop-up visible. 并使弹出窗口可见。 Now this really weird thing occurs where it works on the first try (the pop-up opens with the correct data
information), but after the first try it will display the data
from the previous try. 现在,这确实很奇怪,发生在第一次尝试的地方(弹出窗口打开并显示了正确的data
信息),但是在第一次尝试之后,它将显示先前尝试的data
。
Now what's even weirder is that I tried logging the information on the first try and what I found out is that: 现在更奇怪的是,我第一次尝试记录信息时发现:
$scope.popup
at index.html just before calling $scope.$broadcast('showPopup');
在调用$scope.$broadcast('showPopup');
之前,在index.html上的 $scope.popup
$scope.$broadcast('showPopup');
displays the right information. 显示正确的信息。 $scope.data
at the bitPopup
directive displays null
bitPopup
指令处的$scope.data
显示null
$scope.data
at the bitFalsePositivePopup
directive displays the right information. bitFalsePositivePopup
指令处的$scope.data
显示正确的信息。 On the second try: 在第二次尝试:
$scope.popup
at index.html is correct again. index.html上的$scope.popup
再次正确。 $scope.data
at the bitPopup
directive displays the information from the previous attempt bitPopup
指令处的$scope.data
显示上一次尝试的信息 bitFalsePositivePopup
directive. bitFalsePositivePopup
指令也是bitFalsePositivePopup
。 Another weird thing is that when I use $scope.$apply()
it does work correctly, only it displays the $apply already in progress
error. 另一个奇怪的事情是,当我使用$scope.$apply()
可以正常工作时,仅显示$apply already in progress
错误。 I know I shouldn't use $scope.$apply()
in this case, because it's all Angular events. 我知道在这种情况下不应该使用$scope.$apply()
,因为这都是Angular事件。 But how is it possible that the passed scope is always a step behind? 但是,传递的范围怎么可能总是落后一步呢?
Am I doing something wrong to begin with? 首先我做错了什么吗?
EDIT: 编辑:
Because of amahfouz's answer I decided to post some more code for clarification. 由于amahfouz的回答,我决定发布更多代码进行澄清。 I left out some unimportant details for more clear reading. 我省略了一些不重要的细节,以使阅读更加清晰。
index.html 的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 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 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 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 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服务对弹出窗口的可见性进行更改。
surround your $broadcast event in $timeout like follow: 在$ timeout中包围您的$ broadcast事件,如下所示:
$timeout(function() {
$broadcast('eventName');
});
It will wait for $scope update and then will trigger the event. 它将等待$ scope更新,然后触发事件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.