【问题标题】:Can you use ControllerAs syntax within separate Controllers that share the same view?您可以在共享相同视图的单独控制器中使用 ControllerAs 语法吗?
【发布时间】:2018-03-08 00:19:28
【问题描述】:

问题:

你可以在共​​享相同视图的不同控制器中使用 ControllerAs 语法吗?

ie: (var vm = this)?

困境

我正在尝试消除控制台中由 EsLinter 生成的 linter 错误:

"Designated alias 'vm' is not assigned to 'this' consistent-this" 

我想知道如何在控制器中使用:var vm = this 或将 Controller 设置为 vm(我都尝试过,但没有不工作)

唯一有效的是控制器内的 $scope(如下所示)......每当我尝试将 controller as syntax > 在 controller.js 或 html div 中,并将相关变量 (vm) 应用于 modal.html 中的插值表达式,数据不会呈现。

对此的最佳做法是什么?

** 旁注: 我在将 ng-click 动作函数 绑定到基于控制器的视图时也遇到了问题......下面的示例不起作用(对于动作)——如果我更改 {{: :action}} 到 {{::action()}} 函数在加载时触发,而不是在点击时触发:

modal.html 示例:

<article>
    <h1>{{::title}}</h1>
    <p>{{::body}}</p>
    <button ng-click="{{::action}}">{{::button}}</button>
</article>

HTML 拉入上方 ^

<div class="hide"
     ng-controller="ConfirmModalController"
     ng-include src="'/app/widgets/modals/modal.html'"></div>

<div class="hide"
     ng-controller="ErrorModalController"
     ng-include src="'/app/widgets/modals/modal.html'"></div>

示例控制器

错误控制器

angular
  .module('common.modal')
  .controller('ErrorModalController', ErrorModalController);

function ErrorModalController(modalService, $scope) {

  var vm = $scope;

  vm.title = 'There was an error with your request';

  vm.body = 'Please contact adminstrator regarding this error';

  vm.button = 'Dismiss';

  vm.action = function () {
    console.log("closing modals");
    modalService.closeAllModals();
  };

}

确认控制器

angular
  .module('common.modal')
  .controller('ConfirmModalController', ConfirmModalController);

function ConfirmModalController(modalService, $scope) {

  var vm = $scope;

  vm.title = 'Confirm Your Subscription';

  vm.body = '$8.99 per month will be billed to your account.';

  vm.button = 'Subscribe';

  vm.action = function () {
    console.log("confirming subscription");
    modalService.confirmSubscription();
  };

}

【问题讨论】:

  • 模板不是动态的,将其设为 2 个指令而不是使用 ng-include 会更有意义。
  • 行得通!谢谢!

标签: angularjs scope controller angularjs-controlleras


【解决方案1】:

感谢您的建议 @estus 为每种类型的模态创建指令 - 现在使用 vm=this 正确呈现数据 ...

感谢@JC-Ford 告诉我如何将 {{::action}} 修复为不带括号的 vm.action() ...

** 旁注:(但操作按钮仍有问题)

解决方案 main.html

<confirm-modal></confirm-modal>

解决方案modal.html:

<article>
    <h1>{{::vm.title}}</h1>
    <p>{{::vm.body}}</p>
    <button ng-click="vm.action()">{{::vm.button}}</button>
</article>

解决方案 confirm-modal.directive.js(和控制器)

angular
  .module('common.modal')
  .controller('ConfirmModalController', ConfirmModalController)
  .directive('confirmModal', confirmModal);

/* @ngInject */
function confirmModal() {

  var directive = {
    templateUrl: 'app/widgets/modals/modal.html',
    restrict: 'E',
    controller: ConfirmModalController,
    controllerAs: 'vm',
    bindToController: true
  };

  return directive;
}

function ConfirmModalController(modalService) {

  var vm = this;

  vm.title = 'Confirm Your Subscription';

  vm.body = '$8.99 per month will be billed to your account.';

  vm.button = 'Subscribe';

  vm.action = function () {
    modalService.confirmSubscription();
  };

}

解决错误-modal.directive.js(和控制器)

angular
  .module('common.modal')
  .controller('ErrorModalController', ErrorModalController)
  .directive('errorModal', errorModal);

/* @ngInject */
function errorModal() {
  var directive = {
    templateUrl: 'app/widgets/modals/modal.html',
    restrict: 'E',
    controller: ErrorModalController,
    controllerAs: 'vm',
    bindToController: true
  };

  return directive;
}

function ErrorModalController(modalService) {

  var vm = this;

  vm.title = 'There was an error with your request';

  vm.body = 'Please contact administrator regarding this error';

  vm.button = 'Dismiss';

  vm.action = function () {
    modalService.closeAllModals();
  };
}

【讨论】:

    【解决方案2】:

    数据未呈现,因为您没有在引用中包含控制器。我看不到您在模板中加载控制器的位置,但如果您使用 controllerAs 语法引用控制器,那么要引用其属性,您必须使用该引用。 IOW,如果您将控制器加载为 foo,那么您的模板应如下所示:

    <article>
        <h1>{{::foo.title}}</h1>
        <p>{{::foo.body}}</p>
        <button ng-click="{{::foo.action()}}">{{::foo.button}}</button>
    </article>
    

    在您发布的代码中,您没有使用 controllerAs 语法。您需要使用ng-controller="ConfirmModalController as vm" 加载它。在 JavaScript 和模板中引用它的方式之间没有直接关联。您甚至不必将它们称为相同的东西。

    【讨论】:

    • 感谢您的回复。我实际上尝试过这个并仔细检查以确保。它不起作用。当我在 modal.html 上放入 {{vm.button}} 时,然后在控制器中分配 var vm= this... 然后也在渲染页面上,我正在拉入此模板的特定版本(通过控制器) - (如上图所示) - 说 ng-controller="ConfirmModalController as vm" ...数据仍然没有呈现
    • 好吧,我知道它们不必相同......但是 var vm = this 或 var foo = this .... 是我遇到问题的地方.. . 唯一有效的是当我将该变量应用于 $scope... var vm = $scope 或 var foo = $scope。我正在尝试摆脱控制台中的 linter 错误:“指定别名 'vm' 未分配给 'this' 一致-this”
    • 如果我将 {{::action}} 更改为 {{::action()}} 函数会在加载时触发,而不是在点击时触发
    • 除非您更改了模板,否则您没有使用 controllerAs。
    • 你的意思是在上面的代码中?我故意没有在
      元素中使用这种语法,因为它仍然给我 linter 错误。然后,当我将 vm=this 添加到控制器时,数据不会呈现......所以我的代码中断了。我提出了当前有效的方法(减去操作按钮)......我只是想摆脱 linter 错误。它目前在我编写时正确运行(除了操作按钮)......
    猜你喜欢
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 2019-01-04
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多