5

目标:使用组件而不是使用 $scope 来设置数据。没有要共享的错误,问题是对话框加载组件时未设置数据元素。屏幕截图显示了对话框的当前状态,标签#2(信息)中应该有一个对象绑定。我可以使用 onComplete 事件在对话框加载后验证对象(文档)是否可用。我尝试通过以下方式将对话框调用可用的数据绑定到组件:

在此处输入图像描述

1 使用当地人:

  locals: {
         document: document     
  },
  bindToController: true,
  onComplete: function(){
                    console.log('document: %O', document);
  }

2 使用绑定:

   bindings: {
         document: '='
    }

3 使用解析:

  resolve: {
              document: function() {
                          return document;
                        }
            }

组件:

我相信错误就在这里,绑定,“旧方式”使用 $scope vars 所以绑定毫不费力地连接起来。

(function(){
'use strict';
angular.module('adminClientApp')
.component('documentEdit', {
    templateUrl: 'js/app/components/document/documentEdit/document-edit.html',
    controller: function DocumentEditController($mdToast, $mdMedia) {
       var var documentEdit = this;
        documentEdit.document;

       },
       bindings: {
         document: '<'
       }
    });
  })();

对话调用

DialogController 中只有 $mdDialog 事件。我意识到 locals 和 bindToController 的目标是对话框(DialogController)中指定的控制器。我被难住了——如何将文档设置/传递/连接到组件控制器?

   this.showEdit = function ($event, document) {
                var parentEl = angular.element(document.body);

                $mdDialog.show({
                            parent: parentEl,
                            targetEvent: $event,
                            template: '<div><document-edit document="documentEdit.document"></document-edit></div>',
                            resolve: {
                                       document: function(){ return document;}
                            },
                            controller: DialogController,
                            onComplete: function(){
                                console.log('document: %O', document);
                            }
                        });

        }
4

2 回答 2

4

您没有显示您的 DialogController,但那里可能存在问题。我相信当你给它一个控制器引用时,你还需要给它一个字符串,例如

controller: 'DialogController',

请参阅下面的示例,该示例显示了如何使用 $mdDialog 正确传递值。

(function() {
  angular
    .module('exampleApp', ['ngAnimate', 'ngAria', 'ngMaterial'])
    .controller('ExampleController', ExampleController);

  function ExampleController($mdDialog) {
    var vm = this;
    vm.dialogTemplate = '<md-dialog><md-dialog-content><document-edit document="vm.document"></document-edit></md-dialog-content></md-dialog>';
    vm.document = {
      id: '11',
      name: 'test',
    };
    vm.showLocalsBindedDialog = function(event) {
      $mdDialog.show({
        template: vm.dialogTemplate,
        targetEvent: event,
        clickOutsideToClose: true,
        escapeToClose: true,
        controller: 'DocumentDialogCtrl',
        controllerAs: 'vm',
        bindToController: true,
        locals: {
          'document': vm.document
        }
      });
    }

    vm.showResolveBindedDialog = function(event) {
      $mdDialog.show({
        template: vm.dialogTemplate,
        targetEvent: event,
        clickOutsideToClose: true,
        escapeToClose: true,
        controller: 'DocumentDialogCtrl',
        controllerAs: 'vm',
        bindToController: true,
        resolve: {
          document: function() {
            return vm.document;
          }
        }
      });
    }
  }
  ExampleController.$inject = ['$mdDialog'];
})();

(function() {
  angular
    .module('exampleApp')
    .controller('DocumentDialogCtrl', DocumentDialogCtrl);

  function DocumentDialogCtrl(document) {
    var vm = this;
    vm.document = document;
  }
  DocumentDialogCtrl.$inject = ['document'];
})();

(function() {
  'use strict';
  angular.module('exampleApp')
    .component('documentEdit', {
      bindings: {
        document: '<'
      },
      template: '<p>ID:{{vm.document.id}}</p><p>NAME:{{vm.document.name}}</p>',
      controller: DocumentEditController,
      controllerAs: 'vm'
    });

  function DocumentEditController() {
    var vm = this;
  }
})();
<!DOCTYPE html>
<html ng-app='exampleApp'>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-animate.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-aria.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.9/angular-material.min.css">
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.9/angular-material.min.js"></script>
</head>

<body ng-controller="ExampleController as vm">
  <button ng-click="vm.showLocalsBindedDialog($event)">Show dialog with local passed in values</button>
  <button ng-click="vm.showResolveBindedDialog($event)">Show dialog with resolve passed in values</button>
</body>

</html>

于 2016-07-21T01:29:22.727 回答
3

另一种可能性是使用范围选项。

const tempScope = $rootScope.$new(true);
tempScope.document = document; // This is the local variable

$mdDialog.show({
    scope: tempScope // Give the scope to the dialog
    parent: parentEl,
    targetEvent: $event,
    template: '<document-edit document="document"></document-edit>', // Use scope
    onComplete: function() {
        console.log('document: %O', document);
    }
});

这将为编译模板创建一个临时范围。您仍然需要在模板 ( document="document") 中绑定数据,但可以省略中间控制器。

请注意,如果您想使用resolve来解决承诺,则需要在显示对话框之前手动执行此操作。

于 2016-10-18T08:09:03.057 回答