在 AngularJS 中调用模态指令后重置 $scope 变量
$scope variables reset after calling a modal directive in AngularJS
我正在制作一个 AngularJS 应用程序,它需要处理用户单击的所有复选框并将其保存在一个简单的 ID 数组中。如果数组中有元素并且用户按下打开按钮,则会出现一个模式,用户可以执行操作。现在的问题是,当我在模式中按下关闭按钮时,我不明白为什么,但是包含所有 ID 的数组被重置,我需要重新选择所有复选框以重新保存所有 ID。
这是我的代码
App.js
app.controller("requestsCtrl",["$scope", "$rootScope", "crud", function($scope, $rootScope, crud){
$scope.selectedItemsId = [];
$scope.checkedAllActive = false;
//REQUESTS LOADER
crud.read(null,0, null).then(function(d){
$scope.requests = JSON.parse(JSON.stringify(d.data));
});
//EMIT
$scope.emit = function (emitType, action) {
console.log($scope.selectedItemsId);
$rootScope.$broadcast(emitType, {emitType: emitType, action: action, ids: $scope.selectedItemsId});
};
$scope.checkboxHandler = function (id) {
$rootScope.handleCheckbox($scope.selectedItemsId, id);
};
}]);
app.directive("request", function ($rootScope, $templateCache, $compile, crud) {
return {
restrict: 'E',
scope: { message: "=" },
link: function ($scope, element, attr) {
$scope.name = "request";
$scope.ids = [];
$scope.$on("acceptRequest", function (event, data) {
if(data.action){
console.log("open");
$rootScope.InjectTemplate(element, $scope.name, $scope);
$("#modalBackground").addClass("is-visible");
$scope.ids = data.ids;
$scope.setTask();
}
else {
console.log("close");
$rootScope.RemoveTemplate(element);
$("#modalBackground").removeClass("is-visible");
$scope.ids = [];
}
});
$scope.close = function () {
$scope.$broadcast("acceptRequest", { action: false });
};
$scope.setTask = function () {
if($scope.ids.length > 0){
crud.read($scope.ids.shift(), null, null).then(function (data, err) {
$scope.actualTask = new actualTask(data.data[0]);
});
}
else {
$scope.close();
}
};
$scope.acceptButtonClick = function () {
$rootScope.$broadcast("submit", {});
if($rootScope.date){
var objUpdate = {
id: $scope.actualTask._id
};
console.log($scope.actualTask);
}
};
}
};
});
app.directive("row", function($rootScope){
return {
restrict: 'A',
templateUrl: "row.html",
scope: { data: "=row", triggerController: "=change"},
link: function($scope, element, attrs){
}
};
});
app.run(function ($rootScope, $templateCache, $compile, crud) {
//GLOBAL VARIABLE
$rootScope.date = false;
//------------------
//HANDLE CHECKBOX
$rootScope.handleCheckbox = function (selectedIds, id) {
var i = selectedIds.indexOf(id);
if(i !== -1)
selectedIds.splice(i, 1);
else
selectedIds.push(id);
console.log(selectedIds);
};
//---------------
//DOWNLOAD ACTUAL TASK
$rootScope.ActualTaskOrExit = function (ids) {
if(ids.length > 0){
crud.read(ids.shift(), null, null).then(function (data, err) {
console.log(data.data[0]);
return new actualTask(data.data[0]);
});
}
else {
return false;
}
};
//---------------
//INJECT AND REMOVE TEMPLATE
$rootScope.InjectTemplate = function (element, template, $scope) {
var template = $templateCache.get(template);
element.html(template);
$compile(element.contents())($scope);
};
$rootScope.RemoveTemplate = function (element) {
element.html("");
};
//----------------------------
//DATE FUNCTIONS
$rootScope.fromUTCtoITimestamp = function (data) {
var date = data.split('T')[0];
var hours = data.split('T')[1].substring(0,5);
var year = date.split('-')[0];
var month = date.split('-')[1];
var day = date.split('-')[2];
var hour = hours.split(':')[0];
var minutes = hours.split(':')[1];
return Date.UTC(year, month, day, hour, minutes);
};
$rootScope.fromTimestampToUTC = function (data) {
return new Date(data).toISOString();
};
//--------------------
$rootScope.getModalTemplate = function (modalType) {
return $templateCache.get(modalType);
};
$rootScope.getDate = function (data) {
var t = data.split('T');
var day = t[0].split('-');
var dateOne = day[2] + '/' + day[1] + '/' + day[0];
var hours = t[1].split(':');
var dateTwo = hours[0] + ":" + hours[1];
return dateOne + " " + dateTwo;
};
});
app.service("crud", ["$http","$location", function($http, $location){
var service = this;
service.create = function(obj){
return $http({
method: 'PUT',
url: "/app/create",
data: { obj: obj }
});
};
service.read = function (id, status, date) {
if(id == null && status == null && date == null) return null;
return $http({
method: 'GET',
url: "/app/read",
params: {id: id, status: status, date: date }
});
};
service.delete = function(id){
return $http({
method: 'DELETE',
url: "/app/delete",
params: { id: id }
});
};
service.update = function(obj, path){
return $http({
method: 'PUT',
url: path == 0 ? "/app/update" : "/app/updateProfile" ,
data: { obj: obj }
});
};
}]);
Index.jade
script(type="text/ng-template" id="requests.html")
h1="Richieste"
div
button(ng-click="emit('acceptRequest', true)" ).buttonModify="Accetta"
button(ng-click="emit('removeRequest', true)" ).buttonTerminate="Rimuovi"
table
tr
th
a(ng-click="selectAll()")#selectAll.mdi.mdi-arrow-down-drop-circle.mdi-24px.mdi-light
th="ORDINE"
th="DISPOSITIVO"
th="APPUNTAMENTO"
th="CLIENTE"
tr( ng-repeat="request in requests" id="{{ request._id }}" row="request" change="checkboxHandler")
div#noData
{{ requests.length == 0 ? "Nessuna Richiesta da mostrare" : ""}}
div#modalBackground
request
script(type="text/ng-template" id="row.html")
td
input(type="checkbox" ng-model="check" value="{{ data._id }}" ng-change="triggerController(data._id)" )
td="{{ data.ordercode }}"
td="{{ data.device }}"
td="{{ data.appointment }}"
td="{{ data.name + ' ' + data.surname }}"
使用ng-if directive 添加和删除模态模板。 ng-if
指令创建一个子作用域,以便可以通过销毁子作用域来删除由 $compile
服务创建的任何观察者和指令绑定。否则打开和关闭模态泄漏内存未删除的观察者。
$rootScope
exists, but it can be used for evil
Scopes in AngularJS form a hierarchy, prototypically inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope
and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show
just like values on your local $scope
.
Of course, global state sucks and you should use $rootScope
sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope
, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.
Conversely, don't create a service whose only purpose in life is to store and return bits of data.
我正在制作一个 AngularJS 应用程序,它需要处理用户单击的所有复选框并将其保存在一个简单的 ID 数组中。如果数组中有元素并且用户按下打开按钮,则会出现一个模式,用户可以执行操作。现在的问题是,当我在模式中按下关闭按钮时,我不明白为什么,但是包含所有 ID 的数组被重置,我需要重新选择所有复选框以重新保存所有 ID。
这是我的代码 App.js
app.controller("requestsCtrl",["$scope", "$rootScope", "crud", function($scope, $rootScope, crud){
$scope.selectedItemsId = [];
$scope.checkedAllActive = false;
//REQUESTS LOADER
crud.read(null,0, null).then(function(d){
$scope.requests = JSON.parse(JSON.stringify(d.data));
});
//EMIT
$scope.emit = function (emitType, action) {
console.log($scope.selectedItemsId);
$rootScope.$broadcast(emitType, {emitType: emitType, action: action, ids: $scope.selectedItemsId});
};
$scope.checkboxHandler = function (id) {
$rootScope.handleCheckbox($scope.selectedItemsId, id);
};
}]);
app.directive("request", function ($rootScope, $templateCache, $compile, crud) {
return {
restrict: 'E',
scope: { message: "=" },
link: function ($scope, element, attr) {
$scope.name = "request";
$scope.ids = [];
$scope.$on("acceptRequest", function (event, data) {
if(data.action){
console.log("open");
$rootScope.InjectTemplate(element, $scope.name, $scope);
$("#modalBackground").addClass("is-visible");
$scope.ids = data.ids;
$scope.setTask();
}
else {
console.log("close");
$rootScope.RemoveTemplate(element);
$("#modalBackground").removeClass("is-visible");
$scope.ids = [];
}
});
$scope.close = function () {
$scope.$broadcast("acceptRequest", { action: false });
};
$scope.setTask = function () {
if($scope.ids.length > 0){
crud.read($scope.ids.shift(), null, null).then(function (data, err) {
$scope.actualTask = new actualTask(data.data[0]);
});
}
else {
$scope.close();
}
};
$scope.acceptButtonClick = function () {
$rootScope.$broadcast("submit", {});
if($rootScope.date){
var objUpdate = {
id: $scope.actualTask._id
};
console.log($scope.actualTask);
}
};
}
};
});
app.directive("row", function($rootScope){
return {
restrict: 'A',
templateUrl: "row.html",
scope: { data: "=row", triggerController: "=change"},
link: function($scope, element, attrs){
}
};
});
app.run(function ($rootScope, $templateCache, $compile, crud) {
//GLOBAL VARIABLE
$rootScope.date = false;
//------------------
//HANDLE CHECKBOX
$rootScope.handleCheckbox = function (selectedIds, id) {
var i = selectedIds.indexOf(id);
if(i !== -1)
selectedIds.splice(i, 1);
else
selectedIds.push(id);
console.log(selectedIds);
};
//---------------
//DOWNLOAD ACTUAL TASK
$rootScope.ActualTaskOrExit = function (ids) {
if(ids.length > 0){
crud.read(ids.shift(), null, null).then(function (data, err) {
console.log(data.data[0]);
return new actualTask(data.data[0]);
});
}
else {
return false;
}
};
//---------------
//INJECT AND REMOVE TEMPLATE
$rootScope.InjectTemplate = function (element, template, $scope) {
var template = $templateCache.get(template);
element.html(template);
$compile(element.contents())($scope);
};
$rootScope.RemoveTemplate = function (element) {
element.html("");
};
//----------------------------
//DATE FUNCTIONS
$rootScope.fromUTCtoITimestamp = function (data) {
var date = data.split('T')[0];
var hours = data.split('T')[1].substring(0,5);
var year = date.split('-')[0];
var month = date.split('-')[1];
var day = date.split('-')[2];
var hour = hours.split(':')[0];
var minutes = hours.split(':')[1];
return Date.UTC(year, month, day, hour, minutes);
};
$rootScope.fromTimestampToUTC = function (data) {
return new Date(data).toISOString();
};
//--------------------
$rootScope.getModalTemplate = function (modalType) {
return $templateCache.get(modalType);
};
$rootScope.getDate = function (data) {
var t = data.split('T');
var day = t[0].split('-');
var dateOne = day[2] + '/' + day[1] + '/' + day[0];
var hours = t[1].split(':');
var dateTwo = hours[0] + ":" + hours[1];
return dateOne + " " + dateTwo;
};
});
app.service("crud", ["$http","$location", function($http, $location){
var service = this;
service.create = function(obj){
return $http({
method: 'PUT',
url: "/app/create",
data: { obj: obj }
});
};
service.read = function (id, status, date) {
if(id == null && status == null && date == null) return null;
return $http({
method: 'GET',
url: "/app/read",
params: {id: id, status: status, date: date }
});
};
service.delete = function(id){
return $http({
method: 'DELETE',
url: "/app/delete",
params: { id: id }
});
};
service.update = function(obj, path){
return $http({
method: 'PUT',
url: path == 0 ? "/app/update" : "/app/updateProfile" ,
data: { obj: obj }
});
};
}]);
Index.jade
script(type="text/ng-template" id="requests.html")
h1="Richieste"
div
button(ng-click="emit('acceptRequest', true)" ).buttonModify="Accetta"
button(ng-click="emit('removeRequest', true)" ).buttonTerminate="Rimuovi"
table
tr
th
a(ng-click="selectAll()")#selectAll.mdi.mdi-arrow-down-drop-circle.mdi-24px.mdi-light
th="ORDINE"
th="DISPOSITIVO"
th="APPUNTAMENTO"
th="CLIENTE"
tr( ng-repeat="request in requests" id="{{ request._id }}" row="request" change="checkboxHandler")
div#noData
{{ requests.length == 0 ? "Nessuna Richiesta da mostrare" : ""}}
div#modalBackground
request
script(type="text/ng-template" id="row.html")
td
input(type="checkbox" ng-model="check" value="{{ data._id }}" ng-change="triggerController(data._id)" )
td="{{ data.ordercode }}"
td="{{ data.device }}"
td="{{ data.appointment }}"
td="{{ data.name + ' ' + data.surname }}"
使用ng-if directive 添加和删除模态模板。 ng-if
指令创建一个子作用域,以便可以通过销毁子作用域来删除由 $compile
服务创建的任何观察者和指令绑定。否则打开和关闭模态泄漏内存未删除的观察者。
$rootScope
exists, but it can be used for evilScopes in AngularJS form a hierarchy, prototypically inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject
$rootScope
and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives likeng-show
just like values on your local$scope
.Of course, global state sucks and you should use
$rootScope
sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on$rootScope
, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.Conversely, don't create a service whose only purpose in life is to store and return bits of data.