保存和取消按钮不起作用

时间:2014-05-12 11:08:32

标签: javascript angularjs

我已经在角度js中创建了一个用于添加和删除弹出模型的应用程序,弹出模型即将推出 但是在保存时我得到了未定义并且取消不起作用。

JSFIDDLE

任何人都可以告诉我一些解决方案吗

var app = angular.module('mainApp', ['commonApp', 'ui.bootstrap']);

app.controller('mainController', function ($scope, $rootScope, $modal, $log) {
    $scope.users = [{
        userId: 1,
        userName: "Jhonny"
    }, {
        userId: 2,
        userName: "Sunny"
    }];

    $scope.selectedUsers = {
        users: []
    };

    $scope.open = function (users, dept) {
        var modalInstance = $modal.open({
            templateUrl: 'myModalContent.html',
            controller: 'mainController',
            resolve: {
                usersInModalScope: function () {
                    return users;
                },
                deptInModalScope: function () {
                    return dept;
                }
            }
        });
    };

});


var commonApp = angular.module('commonApp', ['ui.bootstrap']);

commonApp.controller('ModalInstanceCtrl', function ($scope, $rootScope) {
    $scope.cancel = function () {
        $scope.modalInstance.close();
        if ($rootScope.$root.$$phase != '$apply' && $rootScope.$root.$$phase != '$digest') {
            $rootScope.$apply();
        }
    }

    $scope.save = function () {
        alert(JSON.stringify($scope.selectedUsers));
    }
});


commonApp.directive('multiSelect', function ($q) {
    return {
        restrict: 'E',
        controller: "ModalInstanceCtrl",
        require: 'ngModel',
        scope: {
            selectedLabel: "@",
            availableLabel: "@",
            displayAttr: "@",
            available: "=",
            model: "=ngModel",
            eventHandler: '&ngClick'
        },
        template: '<div class="multiSelect">' +
            '<div class="select">' +
            '<label class="control-label" for="multiSelectAvailable">{{ availableLabel }} ' +
            '({{ available.length }})</label>' +
            '<select id="multiSelectAvailable" ng-model="selected.available" multiple ' +
            'ng-options="e as e[displayAttr] for e in available"></select>' +
            '</div>' +
            '<div class="select buttons">' +
            '<button class="btn mover right" ng-click="add()" title="Add selected" ' +
            'ng-disabled="selected.available.length == 0">' +
            '<i class=" icon-arrow-right"></i>' +
            '</button>' +
            '<button class="btn mover left" ng-click="remove()" title="Remove selected" ' +
            'ng-disabled="selected.current.length == 0">' +
            '<i class="icon-arrow-left"></i>' +
            '</button>' +
            '</div>' +
            '<div class="select">' +
            '<label class="control-label" for="multiSelectSelected">{{ selectedLabel }} ' +
            '({{ model.length }})</label>' +
            '<select id="currentRoles" ng-model="selected.current" multiple ' +
            'class="pull-left" ng-options="e as e[displayAttr] for e in model">' +
            '</select>' +
            '</div>' +
            '</div>' +
            '<div class="wrapper text-center">' +
            '<button class="btn btn-default" ng-click="save()"> Save </button>' +
            '<button class="btn btn-default" ng-click="cancel()">Cancel</button>' +
            '</div>',
        link: function (scope, elm, attrs) {
            scope.selected = {
                available: [],
                current: []
            };

            var dataLoading = function (scopeAttr) {
                var loading = $q.defer();
                if (scope[scopeAttr]) {
                    loading.resolve(scope[scopeAttr]);
                } else {
                    scope.$watch(scopeAttr, function (newValue, oldValue) {
                        if (newValue !== undefined) loading.resolve(newValue);
                    });
                }
                return loading.promise;
            };

            var filterOut = function (original, toFilter) {
                var filtered = [];
                angular.forEach(original, function (entity) {
                    var match = false;
                    for (var i = 0; i < toFilter.length; i++) {
                        if (toFilter[i][attrs.displayAttr] == entity[attrs.displayAttr]) {
                            match = true;
                            break;
                        }
                    }
                    if (!match) {
                        filtered.push(entity);
                    }
                });
                return filtered;
            };

            scope.refreshAvailable = function () {
                scope.available = filterOut(scope.available, scope.model);
                scope.selected.available = [];
                scope.selected.current = [];
            };

            scope.add = function () {
                scope.model = scope.model.concat(scope.selected.available);
                scope.refreshAvailable();
            };
            scope.remove = function () {
                scope.available = scope.available.concat(scope.selected.current);
                scope.model = filterOut(scope.model, scope.selected.current);
                scope.refreshAvailable();
            };

            $q.all([dataLoading("model"), dataLoading("available")]).then(function (results) {
                scope.refreshAvailable();
            });
        }
    };

})

2 个答案:

答案 0 :(得分:0)

我很确定你需要在创建模态而不是mainController时引用modalInstanceController。

$scope.open = function (users, dept) {
        var modalInstance = $modal.open({
            templateUrl: 'myModalContent.html',
            controller: 'ModalInstanceCtrl',
            resolve: {
                usersInModalScope: function () {
                    return users;
                },
                deptInModalScope: function () {
                    return dept;
                }
            }
        });
    };

你需要将解决方案传递给控制器​​的参数,$ modalInstance服务也是关闭,解散等方法的地方......

commonApp.controller('ModalInstanceCtrl', function ($scope, $rootScope, $modalInstance, usersInModalScope, deptInModalScope) {
    $scope.cancel = function () {
        $modalInstance.close();
    }

    $scope.save = function () {
        alert(JSON.stringify($scope.selectedUsers));
    }
});

现在已经说过了,我无法让你的实现以你想要的方式工作。但是在我们的ui.bootstrap和模态的实现中,我们使用了这个版本。

<强> ProductsCtrl

angular.module('app', ['ui.bootstrap'])

.controller('AppController', function($scope, $modal, $templateCache) {

  $scope.product = { product: 'I am the product' };

  $scope.openEditProductModal = function () {

    var editProductModal = $modal.open({
        templateUrl: 'edit-product.html',
        controller: 'EditProductModalController',
        resolve: {
            product: function () {
                return $scope.product;
            }
        }
    });

    editProductModal.result.then(function (product) {
        $scope.product = product;
    });
  };


})

模态控制器

.controller('EditProductModalController', function ($scope, $modalInstance, product) {

   $scope.product = product;

   $scope.ok = function () {
            /**
             * Set the edited description and close the modal resolving the promise
             */
            $scope.product = product
            $modalInstance.close($scope.product);
        };

        $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
        };

    })

<强> HTML

  <body ng-controller="AppController">
      <h1 ng-bind="product.product"></h1>
      <br>
      <button ng-click="openEditProductModal(product.product)">Open Modal</button>
      <br>
      <span ng-bind="product.product"></span>
  </body>

修改-Product.html

<div class="modal-header">
  <h3><span class="glyphicon glyphicon-edit"></span> Edit Product</h3>
  <span class="subtitle" ng-bind="product.name"></span>
</div>
<div class="modal-body edit-description-modal">
  <div class="row">
    <input ng-model="product.product"/>
  </div>

</div>
<div class="modal-footer">
  <button class="btn btn-primary" ng-click="ok()">Save</button>
  <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>

链接到Plunkr

答案 1 :(得分:0)

这里

Working Demo $rootScope

Working Demo Factory Version

控制器的范围问题.mainController和ModalInstanceCtrl有自己的范围。它不是同一个范围实例完全不同所以这里$ rootScope是跨应用程序的同一个实例。

首次使用$ rootScope变量进行演示。取决于全局对象真的很糟糕的设计。

要在控制器之间进行通信,您需要像userFactory一样创建factory service,然后传递控制器。在工厂服务中保留你的模态。

var app = angular.module('mainApp', ['commonApp', 'ui.bootstrap']);

app.controller('mainController', function ($scope, $rootScope, $modal, $log, userFactory) {

    $scope.users = userFactory.users;

    $scope.selectedUsers = userFactory.selectedUsers;        

    $scope.open = function (users, dept) {       

        userFactory.modalInstance = $modal.open({
            templateUrl: 'myModalContent.html',
            controller: 'mainController',
            resolve: {
                usersInModalScope: function () {
                    return userFactory.users;
                },
                deptInModalScope: function () {
                    return userFactory.dept;
                }
            }
        });
    };

});

app.factory('userFactory', function (){
    return {
        modalInstance:{},
        users : [{
                    userId: 1,
                    userName: "Jhonny"
                 },
                 {
                    userId: 2,
                    userName: "Sunny"
                 }
                ],

        selectedUsers :{users: []},
        dept : [],
    }
});



var commonApp = angular.module('commonApp', ['ui.bootstrap']);

commonApp.controller('ModalInstanceCtrl', function ($scope, $rootScope, userFactory) {

    $scope.cancel = function () {
        userFactory.modalInstance.close();
        if ($rootScope.$root.$$phase != '$apply' && $rootScope.$root.$$phase != '$digest') {
            $rootScope.$apply();
        }
    }

    $scope.save = function () {
        alert(JSON.stringify(userFactory.selectedUsers));
    }
});


commonApp.directive('multiSelect', function ($q) {
    return {
        restrict: 'E',
        controller: "ModalInstanceCtrl",
        require: 'ngModel',
        scope: {
            selectedLabel: "@",
            availableLabel: "@",
            displayAttr: "@",
            available: "=",
            model: "=ngModel",
            eventHandler: '&ngClick'
        },
        template: '<div class="multiSelect">' +
            '<div class="select">' +
            '<label class="control-label" for="multiSelectAvailable">{{ availableLabel }} ' +
            '({{ available.length }})</label>' +
            '<select id="multiSelectAvailable" ng-model="selected.available" multiple ' +
            'ng-options="e as e[displayAttr] for e in available"></select>' +
            '</div>' +
            '<div class="select buttons">' +
            '<button class="btn mover right" ng-click="add()" title="Add selected" ' +
            'ng-disabled="selected.available.length == 0">' +
            '<i class=" icon-arrow-right"></i>' +
            '</button>' +
            '<button class="btn mover left" ng-click="remove()" title="Remove selected" ' +
            'ng-disabled="selected.current.length == 0">' +
            '<i class="icon-arrow-left"></i>' +
            '</button>' +
            '</div>' +
            '<div class="select">' +
            '<label class="control-label" for="multiSelectSelected">{{ selectedLabel }} ' +
            '({{ model.length }})</label>' +
            '<select id="currentRoles" ng-model="selected.current" multiple ' +
            'class="pull-left" ng-options="e as e[displayAttr] for e in model">' +
            '</select>' +
            '</div>' +
            '</div>' +
            '<div class="wrapper text-center">' +
            '<button class="btn btn-default" ng-click="save()"> Save </button>' +
            '<button class="btn btn-default" ng-click="cancel()">Cancel</button>' +
            '</div>',
        link: function (scope, elm, attrs) {
            scope.selected = {
                available: [],
                current: []
            };

            var dataLoading = function (scopeAttr) {
                var loading = $q.defer();
                if (scope[scopeAttr]) {
                    loading.resolve(scope[scopeAttr]);
                } else {
                    scope.$watch(scopeAttr, function (newValue, oldValue) {
                        if (newValue !== undefined) loading.resolve(newValue);
                    });
                }
                return loading.promise;
            };

            var filterOut = function (original, toFilter) {
                var filtered = [];
                angular.forEach(original, function (entity) {
                    var match = false;
                    for (var i = 0; i < toFilter.length; i++) {
                        if (toFilter[i][attrs.displayAttr] == entity[attrs.displayAttr]) {
                            match = true;
                            break;
                        }
                    }
                    if (!match) {
                        filtered.push(entity);
                    }
                });
                return filtered;
            };

            scope.refreshAvailable = function () {
                scope.available = filterOut(scope.available, scope.model);
                scope.selected.available = [];
                scope.selected.current = [];
            };

            scope.add = function () {
                scope.model = scope.model.concat(scope.selected.available);
                scope.refreshAvailable();
            };
            scope.remove = function () {
                scope.available = scope.available.concat(scope.selected.current);
                scope.model = filterOut(scope.model, scope.selected.current);
                scope.refreshAvailable();
            };

            $q.all([dataLoading("model"), dataLoading("available")]).then(function (results) {
                scope.refreshAvailable();
            });
        }
    };
})