【问题标题】:Pass variable from directive to controller (with ControllerAs vm syntax)将变量从指令传递到控制器(使用 ControllerAs vm 语法)
【发布时间】:2015-02-04 16:48:35
【问题描述】:

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

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

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

因此,例如,您可以在移动设备上获得 6 张图片,在平板电脑上获得 8 张图片,在桌面上获得 12 张图片。

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

由于我对编写自己的指令和 controllerAs vm 语法都很陌生,所以我不知道如何继续。如果我不应该在控制器中注入作用域,我如何访问来自指令的变量?

Code snippets of the custom directive and my controller

【问题讨论】:

  • 我使用的是 Angular 1.3.11

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

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

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

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

这是一个完整的sn-p

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);
})();

【讨论】:

  • 有趣的解决方案,但我想知道这个解决方案是否可重用并且不严格绑定到“ExampleCtrl”。有没有办法可以在我的 HTML 的指令中传递控制器/控制器,以便我也可以将它与其他控制器一起使用?
【解决方案2】:

我不确定你想在这里实现什么。 只要它们不相关,跨多个指令共享控制器就不是一个好主意。您应该为此使用服务。 您可以参考以下链接以了解如何建立此通信 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', []));

【讨论】:

    猜你喜欢
    • 2016-01-11
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多