将变量从指令传递给控制器​​(使用ControllerAs vm语法)

时间:2015-02-04 16:48:36

标签: angularjs angularjs-directive angularjs-scope

我最近阅读了一堆AngularJS样式指南和最佳实践,最后我用using this boilerplate code创建了一个使用Angular,Gulp和Browserify的项目。

上述样板文件使用了大量最佳实践,从文件夹结构和与browserify捆绑到某些angularJS guidelines

我创建了一个简单的属性指令(我的第一个),它将获得$ window.width并且它将在作用域上设置一个特定的变量,具体取决于窗口宽度。 原因是我有一个图像网格,我想有条件地限制显示图片的总量,具体取决于屏幕宽度。本质上,该值将用于渲染所有图片的ngRepeat中的limitTo过滤器。

例如,你可以在手机上获得6张图片,在平板电脑上获得8张图片,在桌面上获得12张。

问题是控制器使用了ControllerAs vm语法,因此我需要在其中注入$ scope,根据前面提到的styleguide是一种不好的做法,只有在绝对必要时才应该使用(例如发布和订阅事件) )

由于我自己编写自己的指令和控制器作为vm语法都相当新,我不知道如何继续。如果我不打算在控制器中注入范围,我该如何访问来自指令的变量?

Code snippets of the custom directive and my controller

2 个答案:

答案 0 :(得分:1)

所以,基本上你想避免使用范围并在html中使用控制器。

我创建了plnkr示例 - 扩展代码。 http://plnkr.co/edit/YOd3KlzTpVviLVuoEBfN?p=preview

在这个例子中,我展示了如何在控制器上定义一个函数,并从html中调用它并在html中访问它的属性。这一切都是在不使用$scope的情况下完成的。

这是一个完整的代码段

<强> HTML

  <div break-limit>
    <p>Title: {{ctrl.title}}</p>
    <p>Number: {{ctrl.number}}</p>
    Limit : {{ctrl.limit}}
    <br>
    <br>
    <input ng-model="ctrl.name"/> 
    <button ng-click="ctrl.sayHello()">Say Hello</button>
  </div>

<强>的.js

   (function() {
  var app = angular.module('myApp', []);

  function ExampleCtrl() {
    var vm = this;

    vm.title = 'AngularJS, using ControllerAs in Directive!';
    vm.number = 1234;
    vm.name = "CASE";

  }

  angular.extend(ExampleCtrl.prototype, {
    sayHello: function() {
      alert('Hello, ' + this.name);
    }
  });

  function breakLimit($window) {
    return {
      controller: ExampleCtrl,
      scope: true,
      controllerAs: 'ctrl',
      link: function(scope, element, attrs, ctrl) {
        var width = $window.innerWidth;
        if (width <= 640) {
          ctrl.limit = 6;
        }
        if (641 <= width <= 1024) {
          ctrl.limit = 8;
        }
        if (1025 <= width <= 1440) {
          ctrl.limit = 12;
        }
      }
    }
  }
  app.directive('breakLimit', breakLimit);
})();

答案 1 :(得分:0)

我不确定你想在这里实现什么。 跨多个指令共享控制器并不是一个好主意,只要它们不相关即可。你应该使用服务。 您可以参考以下链接来了解如何建立此通信 https://github.com/ynmanware/AngTest/tree/master/Angular-unrelated-controller-messaging

我将一个精致的例子贴到了plnkr上 http://plnkr.co/edit/den1mfMeIAWezLTuVZVX?p=preview

<强> HTML

 <body>
   <div ng-app="myApp">
    <div ng-controller="Controller1 as ctrl">
        <br> 
        <table>
            <tr>
                <td><B> Enter Description in Controller1</B></td>
                <td><input type="text" ng-model="ctrl.description"></td>
            </tr>
        </table>
    </div>
    <div ng-controller="Controller2 as ctrl">
        <table>
            <tr>
                <td><B> Description in controller2</B></td>
                <td>{{ctrl.description}}</td>
            </tr>
        </table>
    </div>
</div>
  </body>

<强>的.js

(function(app) {

    function SharedService() {
        var description = "Master";
    }

    angular.extend(SharedService.prototype, {
        getDescription: function() {
            return this.description;
        },
        setDescription: function(desc) {
            this.description = desc;
        }
    });

    function Controller1(SharedService) {
        this.sharedService = SharedService;
    }

    Object.defineProperty(Controller1.prototype,
        'description', {
            enumerable: true, //indicate that it supports enumerations
            configurable: false, //disable delete operation
            get: function() {
                return this.sharedService.getDescription();
            },
            set: function(val) {
                this.sharedService.setDescription(val);
            }
        });

    function Controller2(SharedService) {
        this.sharedService = SharedService;
    }

    Object.defineProperty(Controller2.prototype,
        'description', { //read only property
            enumerable: true,
            configurable: false,
            get: function() {
                return this.sharedService.getDescription();
            }
        });

    app.service('SharedService', SharedService);
    app.controller('Controller1', Controller1);
    app.controller('Controller2', Controller2);

})(angular.module('myApp', []));