【问题标题】:Passing parent 'vm' object to custom directive instead of method(&) and model(=) bindings angular将父“vm”对象传递给自定义指令而不是方法(&)和模型(=)绑定
【发布时间】:2018-05-12 15:40:19
【问题描述】:

有人能帮我理解一下吗?

我有一个包含在控制器中的自定义指令,我想在多个页面中使用相同的指令。指令模板包含按钮,它们的相应操作将在包含指令的控制器中处理。

Controller
------------------------------------------------------------------------
angular
    .module('test')
    .component('approval', {
      template: '<data-table scopeObj ="vm"></data-table>',
      controller: 'PendingApprovalsController',
      controllerAs: 'vm'
    })
    .controller('approvalController', approvalController);

  approvalController.$inject = ['$scope'];
  /* @ngInject */
  function approvalController($scope) {

    var vm = this;


    vm.search1 = function(val) {
       console.log("search1::", val);
     };

     vm.search2 = function(val) {
       console.log("search2::", val);
     };
    vm.search3 = function(val) {
       console.log("search3::", val);
     };
    vm.search4 = function(val) {
       console.log("search4::", val);
     };
    vm.search5 = function(val) {
       console.log("search5::", val);
     };

  }

Directive
---------------------------------------------------------------------
angular.module('test')
    .directive('dataTable', dataTable)
    .controller('dataTableController', dataTableController);

function dataTable( ) {
    return {
      scope: {
        scopeObj: '='
      },
      controller: 'dataTableController',
      controllerAs: 'vm',
      template: '<button class="btn-default" ng-click="scopeObj.search1('search1')">Button1</button> <button class="btn-default" ng-click="scopeObj.search2('search2')">Button2</button>+
        <button class="btn-default" ng-click="scopeObj.search3('search3')">Button3</button><button class="btn-default" ng-click="scopeObj.search4('search4')">Button4</button>'
    };
  }


  dataTableController.$inject = ['$scope'];
  function dataTableController($scope) {

    var vm = this;

  }

1.我可以将指令范围设为假并在多个页面中重复使用指令吗?

2.我可以将控制器“VM”对象传递给指令,而不是传递单个方法,例如

<data-table method1="vm.search1(val)" method2="vm.search2(val)" method3 ="vm.search3(val)" method4="vm.search1(val)"></data-table>

并在指令中访问它们

范围:{ 方法1:'&',方法2:'&',方法3:'&',方法4:'&' }

因为我有太多方法要处理。

【问题讨论】:

    标签: javascript angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    是的,这绝对是您可以做的事情,但您需要进行以下更改才能使其正常工作:

    • 不要使用dataTable 作为指令名称。 data 不允许作为指令名称,因为 AngularJS 会从它找到的每个指令中删除 datadata 是使用属性时的保留关键字。请改用statTable
    • 使用&lt;绑定scopeObj,因为这个问题只需要单向绑定。
    • statTable 中设置bindToController 等于true,这样我们就可以使用controllerAs 语法访问scopeObj 的方法。
    • 在您的模板中,确保使用scope-obj 作为属性名称。请记住,该属性在范围内以 camelCase 形式引用,但在模板中以 kebab-case 形式引用(类似于定义指令)。
    • statTable 模板中,直接调用vm.scopeObj.method() 而不是scopeObj.method(),因为您的scopeObjvm 的属性(因为我们在这里使用controllerAs 语法)。

    把它们放在一起,你就会得到你想要的效果。查看下面的代码以及建议的更改:

    angular.module('test', [])
      .directive('statTable', statTable)
      .controller('statTableController', statTableController)
      .directive('testDirective', testDirective)
      .controller('testDirectiveController', testDirectiveController);
    
    function statTable() {
        return {
        scope: {
            scopeObj: "<"
        },
        bindToController: true,
        controller: "statTableController",
        controllerAs: "vm",
        template: "<button class='btn-default' ng-click='vm.scopeObj.search1(\"search1\")'>Button1</button> <button class=\"btn-default\" ng-click=\"vm.scopeObj.search2('search2')\">Button2</button> <button class=\"btn-default\" ng-click=\"vm.scopeObj.search3('search3')\">Button3</button>"
      };
    }
    
    function statTableController() {
      var vm = this;
      vm.log = console.log;
    }
    
    function testDirective() {
        return {
        controller: "testDirectiveController",
        controllerAs: "vm",
        template: "<stat-table scope-obj='::vm'></stat-table>"
      }
    }
    
    function testDirectiveController() {
      var vm = this;
    
      vm.search1 = function(val) {
            console.log("search1::", val);
      };
    
      vm.search2 = function(val) {
        console.log("search2::", val);
      };
    
      vm.search3 = function(val) {
        console.log("search3::", val);
      };
    }
    

    单击here 以获得工作的 JSFiddle。单击按钮会产生所需的效果。

    【讨论】:

    • 非常感谢您的建议 Christian.Couple 问题,1.如果我们将“vm”对象传递给指令而不是方法绑定,是否会影响性能。 2. 除了将“vm”对象传递给指令外,我可以在指令内使用 scope:false 以便我可以访问父作用域并仍然在多个页面中重用该指令吗?谢谢..
    • 为了获得最大的性能增益,使用 一次性绑定,在 scope-obj 的模板中设置 :: 时添加 scope-obj(我更新了答案和JSFiddle 与此更改)。此设置不会影响性能,因为它不会设置不必要的观察者。至于将scope 设置为false,您可以这样做,但不建议这样做,因为我们希望尽可能坚持使用 Angular 2+ 的组件架构以使升级更容易(有在 Angular 2+ 中没有范围继承)。将statTable 设置为component 而不是directive 也是一个好主意。
    猜你喜欢
    • 2016-06-20
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    相关资源
    最近更新 更多