【问题标题】:$scope variables reset after calling a modal directive in AngularJS在 AngularJS 中调用模态指令后重置 $scope 变量
【发布时间】:2017-03-14 14:50:31
【问题描述】:

我正在制作一个 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 }}"

【问题讨论】:

  • 模式窗口阻止用户访问程序界面的其余部分,直到对话框关闭。因此,您不应过度使用任何创建对话框(或模式窗口)的函数。

标签: javascript angularjs express pug angular-directive


【解决方案1】:

使用ng-if directive 添加和删除模态模板。 ng-if 指令创建一个子作用域,以便可以通过销毁子作用域来删除由$compile 服务创建的任何观察者和指令绑定。否则,模态的打开和关闭会泄漏未移除的观察者的内存。

$rootScope存在,但可以作恶

AngularJS 中的作用域形成一个层次结构,原型继承自树顶部的根作用域。通常这可以忽略,因为大多数视图都有自己的控制器,因此也有自己的作用域。

有时,您想让某些数据对整个应用程序具有全局性。对于这些,您可以注入 $rootScope 并像任何其他范围一样在其上设置值。由于作用域从根作用域继承,这些值将可用于附加到指令的表达式,如 ng-show,就像本地 $scope 上的值一样。

当然,全局状态很糟糕,您应该谨慎使用$rootScope,就像(希望)在任何语言中使用全局变量一样。特别是,不要将其用于代码,只能用于数据。如果您想在 $rootScope 上放置一个函数,最好将它放在一个可以在需要的地方注入并且更容易测试的服务中。

相反,不要创建一个生活中唯一目的是存储和返回数据位的服务。

— AngularJS FAQ

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    相关资源
    最近更新 更多