【问题标题】:Angularjs: How to access main controller from modal controller and directive controllerAngularjs:如何从模态控制器和指令控制器访问主控制器
【发布时间】:2015-11-13 07:36:45
【问题描述】:

我是 Angularjs 的新手,正在从事一个宠物项目。 我有一个在HomeController 中具有功能的主页。然后我在主页上有一个按钮,单击它会打开一个模态,并且该模态有一个名为ModalController 的单独控制器。模态中还有一个指令,它有自己的控制器。我还有 3 个地方需要使用日期选择器,所以我创建了一个日期选择器指令并在所有 3 个地方使用它。

我无法执行以下功能。

  1. 点击edit 我打开了一个对话框,但我需要用行数据打开它,按下保存时应该更新行。 (我在这里遇到的麻烦是如何获取作为指令控制器的日期的值。
  2. 打开 Modal 并输入详细信息并单击保存 我需要创建一个新记录并将其添加到主控制器中存在的记录中。 (如何将数据从 Modal 控制器保存到 Home 控制器记录。

script.js

angular.module('myApp', ['ngAnimate', 'ui.bootstrap']);
angular.module('myApp').controller('HomeController', function($scope, $uibModal) {

  $scope.records = [{'date': new Date(), 'place': 'Bangalore'}];

    $scope.openModal = function() {
      $uibModal.open({
        templateUrl: 'modaldialog.html',
        controller: 'ModalController'
      });
    };

    // How to get the directive date-picker value and pass it and save it.
    $scope.edit = function(record) {
      $uibModal.open({
        templateUrl: 'modaldialog.html',
        controller: 'ModalController'
      });
    };

    $scope.addwithinCtrl = function() {
      var record = {'date': new Date(), 'place': 'Hyderabad'};
      $scope.records.push(record);
    };

});

angular.module('myApp').controller('ModalController', function($scope, $uibModalInstance) {
  // save the input and dismiss the dialog
  $scope.save = function() {
    // how to save the entered data before closing the dialog?
    $uibModalInstance.dismiss('cancel');
  };

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


angular.module('myApp').directive('dateDirective', function() {
  return {
    restrict: 'A',
    templateUrl: 'date.html',
    controller: function($scope) {
      $scope.format = 'dd-MMM-yy';

      $scope.open = function() {
          $scope.status.opened = true;
      };

        $scope.status = {
            opened: false
        };
    }
  }
});

Plunker:PLUNKER

【问题讨论】:

  • 我检查了您的代码,但不明白您为什么将所有 angular-ui 指令与您的代码一起包装。你能告诉我你为什么要为 datepicker 写另一个指令,因为你已经在里面使用了 uib-datepicker?
  • @wickY26 我检查了你的代码,但不明白你为什么用你的那些包装所有 angular-ui 指令我不明白,因为我是这里的初学者。你能详细说明一下吗?

标签: javascript angularjs twitter-bootstrap


【解决方案1】:

您还需要执行多个步骤才能完成任务。关于将数据传入和传出模态控制器以及为 datepicker 设置正确的日期,我将为您提供一个良好的开端。

首先,确保你隔离了日期选择器的范围,它会让你以后的生活更简单。然后将必要的模型传递给该指令并将其绑定到 datepicker(在 datepicker 模板中ng-model="model"):

angular.module('myApp').directive('dateDirective', function() {
    return {
        scope: {
            model: '=ngModel'
        },
        // ... rest of code is unchanged 
    }
});

然后你需要将记录对象传递给模态控制器。为此,您将使用模式的解析指令:

$scope.edit = function(record) {
    $uibModal.open({
        resolve: {
            record: record
        },
        templateUrl: 'modaldialog.html',
        controller: 'ModalController'
    });
};

在 HTML 中,您需要将 record 传递给 edit 函数:

<button class="btn btn-primary" type="button" ng-click="edit(record)">edit</button>

最后,为了更新原始记录,您需要订阅 $uibModal.open 方法返回的已解决承诺:

.controller('ModalController', function($scope, $uibModalInstance, record) {

    $scope.record = angular.copy(record);

    $uibModalInstance.result.then(function() {
        angular.extend(record, $scope.record);
    });

    // ...
});

注意,在模态控制器中,您需要复制原始记录并在模态模板中使用它。这是必要的,因为您只想在按下 Save 时影响原始记录 - 然后您使用更改的数据扩展原始模型。

演示: http://plnkr.co/edit/Hq0wFilQpZ26Ha2nyNxN?p=info

从控制器外部添加新记录

至于你的第二个问题,这是另一个有趣的问题。由于在您的原始代码中您将记录存储在范围数组中,因此对于添加新记录而言,这实际上并不是真正方便的设计解决方案。在现实世界中,您可能会有一个单独的模型层负责获取现有记录并创建新记录。在 Angular 中,您为此使用 services。因此,您需要使用获取、更新和保存记录的方法注册一个新的服务对象。就 MVC 而言,它对应于 M 层。然后,每当您想从任何控制器添加新记录时,您都可以使用此服务,该服务在每个控制器中都是相同的单例对象。

这是一个非常简单的服务示例:

angular.module('myApp').service('records', function() {

    this.data = [{
        'date': new Date(),
        'place': 'Bangalore'
    }];

    this.fetch = function() {
        return this.data;
    };

    this.save = function(record) {
        this.data.push(record);
    };
});

最后,这里是您的问题的完整示例,它可以使用服务从控制器和外部保存新记录,并且还允许编辑。

演示: http://plnkr.co/edit/NxP0HJurZuLA7odzzdie?p=preview

【讨论】:

  • 谢谢。我在这里有几个问题。 1. 隔离日期选择器建议很好,因为我在多个地方使用它。那么我们如何让它隔离呢?还有 scope : { model: ="ngModel" } 做什么? 2. 当我点击保存时,它会调用 $uibModalInstance.close()。所以它又调用 $uibModalInstance.result.then 函数? 3. 你也可以回答我的第二个问题吗?那是如何将新记录从模型控制器添加到 HomeCtrl?我可以在 HomeCtrl 内添加,但不能在它之外添加。
  • 1. {model: ="ngModel"} 指示应该为指令创建新的隔离范围。隔离的scope.model 将绑定到ng-model 属性中传递的外部范围表达式。 2.$uibModalInstance.result是一个promise对象。当您调用$uibModalInstance.close 时,它解决了这个承诺,并且所有使用$uibModalInstance.result.then 注册的回调都会被调用。 3. 将很快更新答案。
  • 查看完整的最终示例,了解您的问题并进行一些解释。
  • 太棒了。例如,我听说过服务感谢。现在我也可以通过在服务中添加删除方法来进行删除。继续摇摆。
  • 酷,很高兴它有帮助。
猜你喜欢
  • 2014-01-03
  • 1970-01-01
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
  • 2016-03-28
  • 1970-01-01
相关资源
最近更新 更多